Markdown is a widely used markup language for writing formatted text. Converting Markdown to HTML in PHP is made easy with the Parsedown library. But what if you need more control over the HTML output, like adding custom classes, IDs, or other attributes dynamically? In this guide, we’ll show you how to create a custom Parsedown class to achieve just that.
Why Customize Parsedown?
Parsedown is a powerful and flexible PHP library for parsing Markdown. However, it doesn’t provide built-in functionality to add custom HTML attributes dynamically. Customizing Parsedown allows you to:
- Enhance HTML Output: Add specific classes, IDs, and other attributes to HTML tags.
- Improve Styling and Functionality: Tailor the HTML to better fit your CSS and JavaScript requirements.
- Maintain Flexibility: Adjust the attributes as needed during the parsing process.
Step-by-Step Guide to Creating a Custom Parsedown
Here’s how you can extend Parsedown to dynamically add HTML attributes during parsing:
1. Create the CustomParsedown Class
Create a new PHP file (e.g., CustomParsedown.php
) and define your custom class:
<?php
require 'vendor/autoload.php'; // Ensure this points to the correct path of your autoload.php
class CustomParsedown extends Parsedown
{
protected $attributes = [];
public function setAttributes(array $attributes)
{
$this->attributes = $attributes;
}
protected function applyAttributes($element, $tagName)
{
if (isset($this->attributes[$tagName])) {
$element['attributes'] = $this->attributes[$tagName];
}
return $element;
}
protected function blockHeader($Line)
{
$Block = parent::blockHeader($Line);
if ($Block) {
$Block['element'] = $this->applyAttributes($Block['element'], $Block['element']['name']);
}
return $Block;
}
protected function blockList($Line, array $CurrentBlock = null)
{
$Block = parent::blockList($Line, $CurrentBlock);
if ($Block) {
$Block['element'] = $this->applyAttributes($Block['element'], $Block['element']['name']);
}
return $Block;
}
protected function inlineLink($Excerpt)
{
$Link = parent::inlineLink($Excerpt);
if ($Link) {
$Link['element'] = $this->applyAttributes($Link['element'], $Link['element']['name']);
}
return $Link;
}
// Add more overridden methods as needed
}
2. Use the CustomParsedown Class
In your main script, use the custom Parsedown class to parse your Markdown text with dynamic attributes:
<?php
// Include the custom Parsedown class
require 'CustomParsedown.php';
// Create a new instance of CustomParsedown
$parsedown = new CustomParsedown();
// Define your attributes
$attributes = [
'h2' => ['class' => 'my-custom-class', 'id' => 'header-id'],
'ul' => ['class' => 'my-list-class'],
'a' => ['target' => '_blank', 'rel' => 'noopener noreferrer']
];
// Set attributes
$parsedown->setAttributes($attributes);
// Your Markdown text
$markdownText = "
# Hello World
## This is an H2 header
This is a sample **Markdown** text with a [link](https://example.com).
- Item 1
- Item 2
- Item 3
";
// Convert Markdown to HTML
$htmlText = $parsedown->text($markdownText);
// Output the HTML
echo $htmlText;
?>
Explanation
- CustomParsedown Class:
- The
CustomParsedown
class extends theParsedown
class. - The
setAttributes
method allows you to set attributes dynamically. - The
applyAttributes
method applies the defined attributes to the specified HTML tags. - The
blockHeader
,blockList
, andinlineLink
methods are overridden to apply attributes to headers, lists, and links respectively.
- The
- Using the Custom Class:
- Include the custom class file.
- Create an instance of the
CustomParsedown
class. - Define and set your attributes using the
setAttributes
method. - Convert Markdown text to HTML with the attributes applied.
Result
The resulting HTML will include the specified attributes:
<h1>Hello World</h1>
<h2 class="my-custom-class" id="header-id">This is an H2 header</h2>
<p>This is a sample <strong>Markdown</strong> text with a <a href="https://example.com" target="_blank" rel="noopener noreferrer">link</a>.</p>
<ul class="my-list-class">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Conclusion
By extending Parsedown, you can add custom HTML attributes to your Markdown content dynamically. This flexibility allows you to enhance the appearance and functionality of your web pages without altering your Markdown content. Follow this guide to create a custom Parsedown class and start adding dynamic attributes to your HTML tags today.
Bonus
To allow passing attributes dynamically along with the text when calling the text method, we need to modify the custom Parsedown class to accept attributes as an argument in the text method. This way, you can set different attributes every time you call it.
Create or update the CustomParsedown.php
file with the following code:
<?php
require 'vendor/autoload.php'; // Ensure this points to the correct path of your autoload.php
class CustomParsedown extends Parsedown
{
protected $attributes = [];
public function text($text, $attributes = [])
{
$this->attributes = $attributes;
return parent::text($text);
}
protected function applyAttributes($element, $tagName)
{
if (isset($this->attributes[$tagName])) {
$element['attributes'] = $this->attributes[$tagName];
}
return $element;
}
protected function blockHeader($Line)
{
$Block = parent::blockHeader($Line);
if ($Block) {
$Block['element'] = $this->applyAttributes($Block['element'], $Block['element']['name']);
}
return $Block;
}
protected function blockList($Line, array $CurrentBlock = null)
{
$Block = parent::blockList($Line, $CurrentBlock);
if ($Block) {
$Block['element'] = $this->applyAttributes($Block['element'], $Block['element']['name']);
}
return $Block;
}
protected function inlineLink($Excerpt)
{
$Link = parent::inlineLink($Excerpt);
if ($Link) {
$Link['element'] = $this->applyAttributes($Link['element'], $Link['element']['name']);
}
return $Link;
}
// Add more overridden methods as needed
}
Using the CustomParsedown Class
In your main script, use the custom Parsedown class to parse your Markdown text with dynamic attributes:
<?php
// Include the custom Parsedown class
require 'CustomParsedown.php';
// Create a new instance of CustomParsedown
$parsedown = new CustomParsedown();
// Your Markdown text
$markdownText = "
# Hello World
## This is an H2 header
This is a sample **Markdown** text with a [link](https://example.com).
- Item 1
- Item 2
- Item 3
";
// Define your attributes
$attributes = [
'h2' => ['class' => 'my-custom-class', 'id' => 'header-id'],
'ul' => ['class' => 'my-list-class'],
'a' => ['target' => '_blank', 'rel' => 'noopener noreferrer']
];
// Convert Markdown to HTML with attributes
$htmlText = $parsedown->text($markdownText, $attributes);
// Output the HTML
echo $htmlText;
?>
By extending Parsedown and modifying the text
method, you can dynamically add custom HTML attributes to your Markdown content every time you parse it. This approach provides greater flexibility and control over the rendered HTML, allowing you to tailor the output to your specific needs.