Rendering User Content - FormatService - Vanilla Success
<main> <article class="userContent"> <p>Vanilla's <code class="code codeInline" spellcheck="false" tabindex="0">FormatService</code> has 1 primary responsibility:</p><div class="blockquote"><div class="blockquote-content"><p class="blockquote-line">Render untrusted user input from a variety of input formats, into a variety of output formats.</p></div></div><h2 data-id="supported-input-formats">Supported Input Formats</h2><ul><li><code class="code codeInline" spellcheck="false" tabindex="0">rich</code> - Vanilla's modern WYSIWYG format. Data is stored as structured JSON.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">bbcode</code> - An artifact from the earlier internet days.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">markdown</code> - Standard markdown with a few extras (spoilers & strikes).</li><li><code class="code codeInline" spellcheck="false" tabindex="0">wysiwyg</code> - Used by vanilla's original WYSIWYG editor. Use this if your HTML doesn't have <code class="code codeInline" spellcheck="false" tabindex="0"><br></code> tags in it.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">html</code> - HTML with <code class="code codeInline" spellcheck="false" tabindex="0"><br></code> tags for newlines.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">text</code> - Plaintext with newlines. Newlines become line breaks during rendering.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">textex</code> - <code class="code codeInline" spellcheck="false" tabindex="0">text</code> with support for a few extras: @mentions, automatic links and automatic embeds.</li></ul><h2 data-id="supported-output-formats">Supported Output Formats</h2><p>Each formatter must implement the following rendering methods:</p><ul><li><code class="code codeInline" spellcheck="false" tabindex="0">renderHTML()</code> - Render HTML output. The output should not use <code class="code codeInline" spellcheck="false" tabindex="0"><br></code> tags for primary line spacing. CSS will give margins to various block level elements. This HTML <strong>should be</strong> sanitized html for XSS and safe to include in its raw form. This should not throw under any circumstances.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">renderPlainText()</code> - Convert the input to plaintext. Notably this <strong>should not be </strong>sanitized for html output and should be appropriate for non-html contexts (like /api/v2/ endpoints). This should not throw under any circumstances.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">renderExcerpt()</code> - Like plaintext, but as a truncated summary. This should not throw under any circumstances.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">renderQuote()</code> - Render HTML but for usage in another user's quote. This may omit certain elements. Rich for example uses this to prevent excessive nesting of quotes inside of quotes. This should not throw under any circumstances.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">filter()</code> - This method should really be called <code class="code codeInline" spellcheck="false" tabindex="0">validate()</code> as it generally behaves the same way as <code class="code codeInline" spellcheck="false" tabindex="0">renderHTML()</code> except it can throw exceptions. It's generally used to validate input.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">parseAttachments()</code> - Parse any inline file attachments from the post content.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">parseHeadings()</code> - Parse any headings from the post content.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">parseImages()</code> - Parse images and alt text from the post content.</li><li><code class="code codeInline" spellcheck="false" tabindex="0">parseMentions()</code> - Parse any user mentions out of the post content.</li></ul><h2 data-id="saving-formatted-content">Saving Formatted Content</h2><ul><li>Formatted content should generally be referred to as <code class="code codeInline" spellcheck="false" tabindex="0">body</code> and <code class="code codeInline" spellcheck="false" tabindex="0">format</code>.</li><li>Formats should be validated on save with the <code class="code codeInline" spellcheck="false" tabindex="0">FormatSchema</code>.</li><li>The body should be validated on save with the <code class="code codeInline" spellcheck="false" tabindex="0">FormatService</code>.</li><li>If you are storing a cached </li></ul><h2 data-id="using-the-formatservice-for-rendering">Using the FormatService for Rendering</h2><pre class="code codeBlock" spellcheck="false" tabindex="0">// Preferred in newer code. // Dependency Inject the format service. $formatted = $this->formatService->renderHtml($body, $format); // Legacy code $formatted = \Gdn::formatService()->renderHtml($body, $format); </pre><h2 data-id="sanitizing-arbitrary-html-content">Sanitizing Arbitrary HTML Content</h2><p>If you have some arbitrary HTML and need to sanitize while preserving as much HTML as possible, <strong>do not</strong><em> </em>use the the HTML format or the FormatService.</p><p>Instead you may dependency inject <code class="code codeInline" spellcheck="false" tabindex="0">HtmlSanitizer::filter()</code> on the content.</p><p>The HTML format applies a lot of additional processing and transformations that are generally undesirable for arbitrary HTML.</p> </article> </main>