maxpertici/markup
最新稳定版本:0.9.2
Composer 安装命令:
composer require maxpertici/markup
包简介
A flexible system for building and rendering HTML markup structures
README 文档
README
📚 Complete Documentation | Getting Started | Markup | MarkupFactory | MarkupSlot | MarkupFinder
A flexible and intuitive PHP library for building HTML markup structures using a fluent, chainable API. Parse existing HTML, modify and manipulate it easily, or create reusable components with slots, manage CSS classes and attributes, and render HTML efficiently.
Introduction
Markup provides a modern, object-oriented approach to handling HTML in PHP. Instead of mixing HTML strings or using complex templating engines, Markup offers:
- ✨ Fluent API - Chain methods for intuitive markup building
- 🎯 Slot System - Named placeholders like Vue.js or Laravel Blade
- 🎨 CSS Class Management - Add, remove, check classes easily
- ⚙️ HTML Attributes - Full control over element attributes
- 🔄 Nested Components - Compose complex structures from simple parts
- 🚀 Dual Rendering -
render()to return string,print()for streaming - 🔁 Conditional & Loop Helpers -
when()andeach()for dynamic content - 🔍 Search & Find - Query your markup tree with CSS selectors
- 📦 Zero Dependencies - Pure PHP, no external requirements
Perfect for building reusable UI components, generating dynamic HTML, or creating a component library for your PHP applications.
Requirements
- PHP 8.1 or higher
Installation
Install via Composer:
composer require maxpertici/markup
Getting Started
Quick Example
<?php require 'vendor/autoload.php'; use MaxPertici\Markup\Markup; // Simple element creation $paragraph = new Markup( wrapper: '<p>%children%</p>', children: ['Hello, World!'] ); echo $paragraph->render(); // Output: <p>Hello, World!</p> // Create with classes and attributes using Markup::make() $div = Markup::make( tag: 'div', classes: ['container', 'text-center'], attributes: ['id' => 'main'] ); $div->append('Content here'); echo $div->render(); // Output: <div class="container text-center" id="main">Content here</div> // Parse existing HTML with Markup::fromHtml() $card = Markup::fromHtml( html: '<div class="card"><h2>Title</h2></div>' ); $card->addClass('shadow') ->setAttribute('data-enhanced', 'true'); echo $card->render(); // Output: <div class="card shadow" data-enhanced="true"><h2>Title</h2></div>
Creating Components
// Card component $card = new Markup( wrapper: '<div class="card">%children%</div>' ); $card->children( new Markup( wrapper:'<h2 class="card-title">%children%</h2>', children: ['Card Title'] ), new Markup( wrapper:'<p class="card-body">%children%</p>', children: ['Card content'] ) ); echo $card->render();
Output:
<div class="card"> <h2 class="card-title">Card Title</h2> <p class="card-body">Card content</p> </div>
Managing Classes and Attributes
$button = new Markup( wrapper: '<button class="%classes%" %attributes%>%children%</button>', wrapperClasses: ['btn', 'btn-primary'], wrapperAttributes: ['type' => 'submit', 'id' => 'submit-btn'], children: ['Submit'] ); echo $button->render(); // Output: <button class="btn btn-primary" type="submit" id="submit-btn">Submit</button> // Modify classes and attributes $button->addClass('btn-lg') ->removeClass('btn-primary') ->addClass('btn-secondary') ->setAttribute('disabled', 'true'); // Check classes if ($button->hasClass('btn-secondary')) { echo "Button is secondary"; }
Using Slots
use MaxPertici\Markup\MarkupSlot; // Define layout with slots $layout = new Markup('<div class="layout">%children%</div>'); $layout->children( new MarkupSlot('header', '<header>%slot%</header>'), new MarkupSlot('content', '<main>%slot%</main>'), new MarkupSlot('footer', '<footer>%slot%</footer>') ); // Fill the slots $layout->slot('header', ['<h1>My Website</h1>']) ->slot('content', ['<p>Welcome!</p>']) ->slot('footer', ['<p>© 2024</p>']); echo $layout->render();
Finding and Manipulating Elements
// Build a page structure $page = Markup::make( tag: 'div', classes: ['page'] )->children( Markup::make( tag: 'header', classes: ['header'] ), Markup::make( tag: 'main', classes: ['content'] )->children( Markup::make( tag: 'p', classes: ['intro'] )->append('Introduction text'), Markup::make( tag: 'p', classes: ['highlight'] )->append('Important note') ) ); // Find elements using CSS selectors $headers = $page->find()->css('.header')->get(); $paragraphs = $page->find()->css('main p')->get(); $highlighted = $page->find()->css('.highlight')->first(); // Modify found elements with collection methods $page->find()->css('.intro')->get() ->each(fn($intro) => $intro->addClass('text-large')); // Filter and transform $page->find()->tag('p')->get() ->filter(fn($p) => $p->hasClass('intro')) ->each(fn($p) => $p->addClass('featured'));
Conditional and Loops
// Conditional rendering $card = Markup::make( tag: 'div', classes: ['card'] )->append('Regular content'); $isAdmin = true; $card->when($isAdmin, function($markup) { $markup->append( Markup::make( tag: 'div', classes: ['admin-panel']) ->append('Admin tools') ); }); // Loop through data $users = [ ['name' => 'Alice', 'email' => 'alice@example.com'], ['name' => 'Bob', 'email' => 'bob@example.com'], ]; $list = Markup::make(tag: 'ul'); $list->each($users, function($user, $index, $markup) { $markup->append( Markup::make(tag: 'li') ->append("{$user['name']} - {$user['email']}") ); }); echo $list->render();
Nested Lists with MarkupFlow
Use MarkupFlow to create complex nested structures:
use MaxPertici\Markup\MarkupFlow; $nav = new Markup( wrapper: '<ul>%children%</ul>', childrenWrapper: '<li>%child%</li>', children: [ 'Home', 'About', new MarkupFlow([ 'Products', new Markup( wrapper: '<ul>%children%</ul>', children: [ '<li>Electronics</li>', '<li>Clothing</li>', '<li>Books</li>', ] ), ]), 'Contact', ] ); echo $nav->render();
Output:
<ul> <li>Home</li> <li>About</li> <li> Products <ul> <li>Electronics</li> <li>Clothing</li> <li>Books</li> </ul> </li> <li>Contact</li> </ul>
MarkupFlow allows you to group multiple elements that will be rendered sequentially within a parent element, perfect for creating nested structures.
Real-World Example: Web Scraping
Fetch HTML from a URL and extract content:
use MaxPertici\Markup\Markup; // Fetch and parse HTML $html = file_get_contents('https://example.com/blog'); $page = Markup::fromHtml(html: $html); // Find articles and process with collection methods $articles = $page->find()->tag('article')->get(); $articles->each(function($article) { // Get title and excerpt $title = $article->find()->tag('h2')->first(); $excerpt = $article->find()->tag('p')->first(); if ($title) { echo "Title: " . $title->text() . "\n"; } if ($excerpt) { echo "Excerpt: " . $excerpt->text() . "\n"; } echo "---\n"; });
Use collection methods to filter and transform:
// Get only featured articles $featured = $page->find()->tag('article')->get() ->filter(fn($article) => $article->hasClass('featured')); // Extract all titles $titles = $page->find()->tag('article')->get() ->map(fn($article) => $article->find()->tag('h2')->first()) ->filter(fn($title) => $title !== null) ->map(fn($title) => $title->text()); // Take first 5 articles and enhance them $page->find()->tag('article')->get() ->take(5) ->each(fn($article) => $article->addClass('featured-item')); echo $page->render();
Documentation
For complete documentation, examples, and API reference, visit:
📖 Complete Documentation
Main Sections
- Getting Started - Installation and basic usage
- Markup - Core Markup class with all HTML manipulation methods
- MarkupFactory - Factory methods and HTML parsing
- MarkupQueryBuilder - Fluent interface for searching elements
- MarkupCollection - Collection methods for working with multiple elements
- MarkupFinder - Advanced search and filtering capabilities
- MarkupFlow - Group elements without wrapper
- MarkupSlot - Slot system for reusable components
Key Features
Factory Methods
Create elements quickly with Markup::make() (shortcut for MarkupFactory::create()):
// Create elements with Markup::make() $div = Markup::make( tag: 'div', classes: ['container'], attributes: ['id' => 'main'] ); $div->append('Content here'); // Or use MarkupFactory directly $div = MarkupFactory::create( tag: 'div', classes: ['container'], attributes: ['id' => 'main'] ); // Parse HTML with Markup::fromHtml() $markup = Markup::fromHtml(html: '<div class="box">Content</div>'); $markup->addClass('shadow'); // Or use MarkupFactory directly $markup = MarkupFactory::fromHtml(html: '<div class="box">Content</div>'); // Use predefined elements with enums use MaxPertici\Markup\Elements\HtmlTag; $button = MarkupFactory::fromElement( element: HtmlTag::BUTTON, children: ['Click me'], classes: ['btn', 'btn-primary'] );
CSS Selector Queries
Find elements using familiar CSS selector syntax:
$page->find()->css('.section')->get(); // by class $page->find()->css('div')->get(); // by tag $page->find()->css('#hero')->first(); // by ID $page->find()->css('[role="main"]')->get(); // by attribute $page->find()->css('nav li.active')->get(); // combined $page->find()->css('.header > nav')->get(); // direct child $page->find()->css('nav:has(li.active)')->get(); // has pseudo-class
Collection Methods
Work with multiple elements using powerful collection methods:
// Filter elements $featured = $page->find()->tag('article')->get() ->filter(fn($article) => $article->hasClass('featured')); // Map and transform $titles = $page->find()->tag('h2')->get() ->map(fn($title) => $title->text()); // Take subset $first5 = $page->find()->tag('p')->get()->take(5); // Iterate with each $page->find()->css('.card')->get() ->each(fn($card) => $card->addClass('enhanced')); // Chain methods $page->find()->tag('article')->get() ->filter(fn($article) => $article->hasClass('published')) ->take(10) ->each(fn($article) => $article->addClass('featured'));
Enum-Based Components
Create reusable component libraries with PHP enums:
use MaxPertici\Markup\Contracts\MarkupElementInterface; enum BootstrapComponent implements MarkupElementInterface { case CARD; case BUTTON_PRIMARY; case ALERT_SUCCESS; // ... implement required methods } $card = MarkupFactory::fromElement( element: BootstrapComponent::CARD, classes: ['Card content'] );
License
This project is licensed under the MIT License - see the LICENSE file for details.
Credits
Author: Max Pertici
Email: hello@maxpertici.fr
Website: maxpertici.fr
Support
- 📚 Documentation: https://maxpertici.github.io/markup/
- 🐛 Issues: GitHub Issues
- ✉️ Email: hello@maxpertici.fr
Made with ❤️ by Max Pertici
统计信息
- 总下载量: 17
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-14