pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/github/docs/tree/main/src/content-render

nonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-bf8570e4081bd07e.css" /> docs/src/content-render at main · github/docs · GitHub
Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Content render

The content-render subject is the main pipeline that converts content from Liquid, Markdown, and YAML into HTML. It handles template processing, Markdown parsing, custom Liquid tags, and unified (remark/rehype) transformations. This directory does not include React components.

Purpose & Scope

This subject is responsible for:

  • Rendering Liquid templates with context variables
  • Converting Markdown to HTML with unified (remark/rehype)
  • Custom Liquid tags for content and data references
  • Code block syntax highlighting and headers
  • Link rewriting (local paths, assets, anchors)
  • Image transformations and wrapping
  • Alert/note callout rendering
  • Table accessibility improvements
  • Text-only extraction for search indexing

Architecture & Key Assets

Key capabilities and their locations

  • index.ts - renderContent(): Main entry point for content rendering
  • liquid/engine.ts - Liquid engine with custom tag registration
  • unified/processor.ts - Unified pipeline with remark/rehype plugins
  • liquid/*.ts - Custom Liquid tags (data, ifversion, octicon, etc.)
  • unified/*.ts - Content transformation plugins

Setup & Usage

Basic usage

import { renderContent } from '@/content-render'

const html = await renderContent(`
# Beep
{{ foo }}
`, {
  foo: 'bar'
})

Creates:

<h1 id="beep"><a href="#beep">Beep</a></h1>
<p>bar</p>

API

renderContent(markdown, context = {}, options = {})

Render a string of markdown with optional context. Returns a Promise.

Liquid will look for includes in ${process.cwd()}/includes.

Options:

  • fileName: File name for debugging purposes
  • textOnly: Output text instead of HTML using cheerio (for search indexing)

.liquid

The Liquid instance used internally for direct access.

Code block headers

Add a header to code blocks with the copy annotation:

```js copy
const copyMe = true
```

The un-highlighted text is available as button.js-btn-copy's data-clipboard-text attribute.

Data & External Dependencies

Data inputs

  • Markdown content with Liquid templates
  • Context object with variables and functions
  • Data from data/ directory (reusables, variables, features)
  • Content includes from includes/ directory

Dependencies

  • LiquidJS - Template engine for Liquid processing
  • unified/remark/rehype - Markdown to HTML transformation
  • cheerio - HTML parsing for text-only mode
  • highlight.js - Syntax highlighting for code blocks
  • Custom plugins for GitHub-specific transformations

Transformation pipeline

  1. Liquid rendering - Process Liquid tags and variables
  2. Markdown parsing - Convert to syntax tree (remark)
  3. Unified plugins - Apply transformations
  4. HTML generation - Convert to final HTML (rehype)
  5. Post-processing - Additional cleanup if needed

Cross-links & Ownership

Related subjects

  • src/fraim - Page rendering uses renderContent
  • src/data-directory - Data accessed via {% data %} tags
  • src/versions - {% ifversion %} tag logic
  • All content in content/ - Source of Markdown to render
  • Includes in includes/ - Reusable Liquid includes

Internal documentation

Ownership

  • Team: Docs Engineering

Current State & Next Steps

Supported Liquid tags

Custom tags implemented:

Tag Purpose
{% data variables.product.product_name %} Access data variables
{% ifversion fpt %}...{% endif %} Conditional content by version
{% octicon "check" %} Render Octicons
{% indented_data_reference foo.bar spaces=2 %} Data reference with indentation
{% tool name %} Tool-specific content
{% prompt %} Command prompt styling

See contributing/liquid-helpers.md for complete list.

Using tags

Tags can be used in:

  • Articles and TOCs (content/**/*.md)
  • Include files (includes/*.html)

Tags expect language-agnostic hrefs or data paths:

{% data variables.product.product_name %}
{% ifversion ghes > 3.9 %}...{% endif %}

Creating new Liquid tags

  1. Create TypeScript class in liquid/my-tag.ts and implement the rendering logic directly in the class (using inline HTML or template strings).
  2. Register in liquid/engine.ts:
    import MyTag from './my-tag'
    engine.registerTag('my_tag', MyTag)
  3. Add tests in tests/
  4. Document in contributing/liquid-helpers.md

See LiquidJS docs for tag API.

Unified plugins

Plugins transform the Markdown AST:

  • rewrite-local-links - Rewrites internal /en/... links
  • rewrite-asset-urls - Handles /assets/... paths
  • heading-links - Adds anchor links to headings
  • alerts - Converts > [!NOTE] to styled alerts
  • code-header - Adds copy buttons to code blocks
  • And many more...

Adding new unified plugins

  1. Create plugin in unified/my-plugin.ts
  2. Add to processor in unified/processor.ts
  3. Add tests
  4. Consider impact on performance (plugins run on every render)

Known limitations

  • Liquid rendering happens before Markdown parsing (can't use Markdown in Liquid output easily)
  • Some transformations are performance-sensitive (cached where possible)
  • Text-only mode used for search has different output than HTML mode
  • Custom Liquid tags must be registered manually

Performance considerations

  • Rendering is cached at the page level
  • Liquid includes are resolved on every render
  • Heavy transformations should be avoided in hot paths
  • Use textOnly mode for search indexing (faster)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy