Publisher - Modèles Personnalisés
Modèles Personnalisés dans Publisher
Section intitulée « Modèles Personnalisés dans Publisher »Guide pour créer et personnaliser les modèles de Publisher en utilisant les remplacements Smarty, CSS et HTML.
Aperçu du Système de Modèles
Section intitulée « Aperçu du Système de Modèles »Qu’est-ce que les Modèles ?
Section intitulée « Qu’est-ce que les Modèles ? »Les modèles contrôlent comment Publisher affiche le contenu :
Les modèles affichent : ├── Affichage des articles ├── Listes des catégories ├── Pages d'archive ├── Listes d'articles ├── Sections de commentaires ├── Résultats de recherche ├── Blocs └── Pages d'administrationTypes de Modèles
Section intitulée « Types de Modèles »Modèles de Base : ├── publisher_index.tpl (accueil du module) ├── publisher_item.tpl (article unique) ├── publisher_category.tpl (page de catégorie) └── publisher_archive.tpl (affichage d'archive)
Modèles de Blocs : ├── publisher_block_latest.tpl ├── publisher_block_categories.tpl ├── publisher_block_archives.tpl └── publisher_block_top.tpl
Modèles Admin : ├── admin_articles.tpl ├── admin_categories.tpl └── admin_*Template Directories
Section intitulée « Template Directories »Template File Structure
Section intitulée « Template File Structure »XOOPS Installation:├── modules/publisher/│ └── templates/│ ├── Publisher/ (base templates)│ │ ├── publisher_index.tpl│ │ ├── publisher_item.tpl│ │ ├── publisher_category.tpl│ │ ├── blocks/│ │ │ ├── publisher_block_latest.tpl│ │ │ └── publisher_block_categories.tpl│ │ └── css/│ │ └── publisher.css│ └── Themes/ (theme-specific)│ ├── Classic/│ ├── Modern/│ └── Dark/
themes/yourtheme/└── modules/ └── publisher/ ├── templates/ │ └── publisher_custom.tpl ├── css/ │ └── custom.css └── images/ └── icons/Template Hierarchy
Section intitulée « Template Hierarchy »graph TD A[XOOPS looks for template] -->|First| B[Theme-specific template] B -->|If not found| C[Module default template] C -->|If not found| D[Fallback/error]Creating Custom Templates
Section intitulée « Creating Custom Templates »Copy Template to Theme
Section intitulée « Copy Template to Theme »Method 1: Via File Manager
1. Navigate to /themes/yourtheme/modules/publisher/2. Create directory if not exists: - templates/ - css/ - js/ (optional)3. Copy module template file: modules/publisher/templates/Publisher/publisher_item.tpl → themes/yourtheme/modules/publisher/templates/publisher_item.tpl4. Edit theme copy (not module copy!)Method 2: Via FTP/SSH
# Create theme override directorymkdir -p /path/to/xoops/themes/yourtheme/modules/publisher/templates
# Copy template filescp /path/to/xoops/modules/publisher/templates/Publisher/*.tpl \ /path/to/xoops/themes/yourtheme/modules/publisher/templates/
# Verify files copiedls /path/to/xoops/themes/yourtheme/modules/publisher/templates/Edit Custom Template
Section intitulée « Edit Custom Template »Open theme copy in text editor:
File: /themes/yourtheme/modules/publisher/templates/publisher_item.tpl
Edit: 1. Keep Smarty variables intact 2. Modify HTML structure 3. Add custom CSS classes 4. Adjust display logicSmarty Template Basics
Section intitulée « Smarty Template Basics »Smarty Variables
Section intitulée « Smarty Variables »Publisher provides variables to templates:
Article Variables
Section intitulée « Article Variables »{* Single Article Variables *}<h1>{$item->title()}</h1><p>{$item->description()}</p><p>{$item->body()}</p><p>By {$item->uname()} on {$item->date('l, F j, Y')}</p><p>Category: {$item->category}</p><p>Views: {$item->views()}</p>Category Variables
Section intitulée « Category Variables »{* Category Variables *}<h2>{$category->name()}</h2><p>{$category->description()}</p><img src="{$category->image()}" alt="{$category->name()}"><p>Articles: {$category->itemCount()}</p>Block Variables
Section intitulée « Block Variables »{* Latest Articles Block *}{foreach from=$items item=item} <div class="article"> <h3>{$item->title()}</h3> <p>{$item->summary()}</p> </div>{/foreach}Common Smarty Syntax
Section intitulée « Common Smarty Syntax »{* Variable *}{$variable}{$array.key}{$object->method()}
{* Conditional *}{if $condition} <p>Content shown if true</p>{else} <p>Content shown if false</p>{/if}
{* Loop *}{foreach from=$array item=item} <li>{$item}</li>{/foreach}
{* Functions *}{$variable|truncate:100:"..."}{$date|date_format:"%Y-%m-%d"}{$text|htmlspecialchars}
{* Comments *}{* This is a Smarty comment, not displayed *}Template Examples
Section intitulée « Template Examples »Single Article Template
Section intitulée « Single Article Template »File: publisher_item.tpl
<!-- Article Detail View --><div class="publisher-item">
<!-- Header Section --> <div class="article-header"> <h1>{$item->title()}</h1>
{if $item->subtitle()} <h2 class="article-subtitle">{$item->subtitle()}</h2> {/if}
<div class="article-meta"> <span class="author"> By <a href="{$item->authorUrl()}">{$item->uname()}</a> </span> <span class="date"> {$item->date('l, F j, Y')} </span> <span class="category"> <a href="{$item->categoryUrl()}"> {$item->category} </a> </span> <span class="views"> {$item->views()} views </span> </div> </div>
<!-- Featured Image --> {if $item->image()} <div class="article-featured-image"> <img src="{$item->image()}" alt="{$item->title()}" class="img-fluid"> </div> {/if}
<!-- Article Body --> <div class="article-content"> {$item->body()} </div>
<!-- Tags --> {if $item->tags()} <div class="article-tags"> <strong>Tags:</strong> {foreach from=$item->tags() item=tag} <span class="tag"> <a href="{$tag->url()}">{$tag->name()}</a> </span> {/foreach} </div> {/if}
<!-- Footer Section --> <div class="article-footer"> <div class="article-actions"> {if $canEdit} <a href="{$editUrl}" class="btn btn-primary">Edit</a> {/if} {if $canDelete} <a href="{$deleteUrl}" class="btn btn-danger">Delete</a> {/if} </div>
{if $allowRatings} <div class="article-rating"> <!-- Rating component --> </div> {/if} </div>
</div>
<!-- Comments Section -->{if $allowComments} <div class="article-comments"> <h3>Comments</h3> {include file="publisher_comments.tpl"} </div>{/if}Category Listing Template
Section intitulée « Category Listing Template »File: publisher_category.tpl
<!-- Category Page --><div class="publisher-category">
<!-- Category Header --> <div class="category-header"> <h1>{$category->name()}</h1>
{if $category->image()} <img src="{$category->image()}" alt="{$category->name()}" class="category-image"> {/if}
{if $category->description()} <p class="category-description"> {$category->description()} </p> {/if} </div>
<!-- Subcategories --> {if $subcategories} <div class="subcategories"> <h3>Subcategories</h3> <ul> {foreach from=$subcategories item=sub} <li> <a href="{$sub->url()}">{$sub->name()}</a> ({$sub->itemCount()} articles) </li> {/foreach} </ul> </div> {/if}
<!-- Articles List --> <div class="articles-list"> <h2>Articles</h2>
{if count($items) > 0} {foreach from=$items item=item} <article class="article-preview"> {if $item->image()} <div class="article-image"> <a href="{$item->url()}"> <img src="{$item->image()}" alt="{$item->title()}"> </a> </div> {/if}
<div class="article-content"> <h3> <a href="{$item->url()}">{$item->title()}</a> </h3>
<div class="article-meta"> <span class="date">{$item->date('M d, Y')}</span> <span class="author">by {$item->uname()}</span> </div>
<p class="article-excerpt"> {$item->description()|truncate:200:"..."} </p>
<a href="{$item->url()}" class="read-more"> Read More → </a> </div> </article> {/foreach}
<!-- Pagination --> {if $pagination} <nav class="pagination"> {$pagination} </nav> {/if} {else} <p class="no-articles"> No articles in this category yet. </p> {/if} </div>
</div>Latest Articles Block Template
Section intitulée « Latest Articles Block Template »File: publisher_block_latest.tpl
<!-- Latest Articles Block --><div class="publisher-block-latest"> <h3>{$block_title|default:"Latest Articles"}</h3>
{if count($items) > 0} <ul class="article-list"> {foreach from=$items item=item name=articles} <li class="article-item"> <a href="{$item->url()}" title="{$item->title()}"> {$item->title()} </a> <span class="date"> {$item->date('M d, Y')} </span>
{if $show_summary && $item->description()} <p class="summary"> {$item->description()|truncate:80:"..."} </p> {/if} </li> {/foreach} </ul> {else} <p>No articles available.</p> {/if}</div>Styling with CSS
Section intitulée « Styling with CSS »Custom CSS Files
Section intitulée « Custom CSS Files »Create custom CSS in theme:
/themes/yourtheme/modules/publisher/css/custom.cssBase Template Structure
Section intitulée « Base Template Structure »Understand the HTML structure:
<!-- Publisher Module --><div class="publisher-module">
<!-- Item View --> <div class="publisher-item"> <div class="article-header">...</div> <div class="article-featured-image">...</div> <div class="article-content">...</div> <div class="article-footer">...</div> </div>
<!-- Category View --> <div class="publisher-category"> <div class="category-header">...</div> <div class="articles-list">...</div> </div>
<!-- Block --> <div class="publisher-block-latest"> <ul class="article-list">...</ul> </div>
</div>CSS Examples
Section intitulée « CSS Examples »/* Article Container */.publisher-item { background: #fff; border: 1px solid #ddd; border-radius: 4px; padding: 20px; margin-bottom: 20px;}
/* Article Header */.article-header { border-bottom: 2px solid #f0f0f0; padding-bottom: 15px; margin-bottom: 20px;}
.article-header h1 { font-size: 2.5em; margin: 0 0 10px 0; color: #333;}
.article-subtitle { font-size: 1.3em; color: #666; font-style: italic; margin: 0;}
/* Article Meta Information */.article-meta { font-size: 0.9em; color: #999;}
.article-meta span { margin-right: 20px;}
.article-meta a { color: #0066cc; text-decoration: none;}
.article-meta a:hover { text-decoration: underline;}
/* Article Featured Image */.article-featured-image { margin: 20px 0; text-align: center;}
.article-featured-image img { max-width: 100%; height: auto; border-radius: 4px;}
/* Article Content */.article-content { font-size: 1.1em; line-height: 1.8; color: #333;}
.article-content h2 { font-size: 1.8em; margin: 30px 0 15px 0; color: #222;}
.article-content h3 { font-size: 1.4em; margin: 20px 0 10px 0; color: #444;}
.article-content p { margin-bottom: 15px;}
.article-content ul,.article-content ol { margin: 15px 0 15px 30px;}
.article-content li { margin-bottom: 8px;}
/* Article Tags */.article-tags { margin-top: 20px; padding-top: 20px; border-top: 1px solid #f0f0f0;}
.tag { display: inline-block; background: #f0f0f0; padding: 5px 10px; margin: 5px 5px 5px 0; border-radius: 3px; font-size: 0.9em;}
.tag a { color: #0066cc; text-decoration: none;}
.tag a:hover { text-decoration: underline;}
/* Category Articles List */.publisher-category .articles-list { margin-top: 30px;}
.article-preview { display: flex; margin-bottom: 30px; padding-bottom: 30px; border-bottom: 1px solid #f0f0f0;}
.article-preview:last-child { border-bottom: none;}
.article-image { flex: 0 0 200px; margin-right: 20px;}
.article-image img { width: 100%; height: 150px; object-fit: cover; border-radius: 4px;}
.article-content { flex: 1;}
/* Responsive */@media (max-width: 768px) { .article-preview { flex-direction: column; }
.article-image { flex: 1; margin: 0 0 15px 0; }
.article-header h1 { font-size: 1.8em; }}Template Variables Reference
Section intitulée « Template Variables Reference »Item (Article) Object
Section intitulée « Item (Article) Object »{* Article Properties *}{$item->id()} {* Article ID *}{$item->title()} {* Article title *}{$item->description()} {* Short description *}{$item->body()} {* Full content *}{$item->subtitle()} {* Subtitle *}{$item->uname()} {* Author username *}{$item->authorId()} {* Author user ID *}{$item->date()} {* Publication date *}{$item->modified()} {* Last modified *}{$item->image()} {* Featured image URL *}{$item->views()} {* View count *}{$item->categoryId()} {* Category ID *}{$item->category()} {* Category name *}{$item->categoryUrl()} {* Category URL *}{$item->url()} {* Article URL *}{$item->status()} {* Article status *}{$item->rating()} {* Average rating *}{$item->comments()} {* Comment count *}{$item->tags()} {* Article tags array *}
{* Formatted Methods *}{$item->date('Y-m-d')} {* Formatted date *}{$item->description()|truncate:100} {* Truncated *}Category Object
Section intitulée « Category Object »{* Category Properties *}{$category->id()} {* Category ID *}{$category->name()} {* Category name *}{$category->description()} {* Description *}{$category->image()} {* Image URL *}{$category->parentId()} {* Parent category ID *}{$category->itemCount()} {* Article count *}{$category->url()} {* Category URL *}{$category->status()} {* Status *}Block Variables
Section intitulée « Block Variables »{$items} {* Array of items *}{$categories} {* Array of categories *}{$pagination} {* Pagination HTML *}{$total} {* Total count *}{$limit} {* Items per page *}{$page} {* Current page *}Template Conditionals
Section intitulée « Template Conditionals »Common Conditional Checks
Section intitulée « Common Conditional Checks »{* Check if variable exists and is not empty *}{if $variable} <p>{$variable}</p>{/if}
{* Check if array has items *}{if count($items) > 0} {foreach from=$items item=item} <li>{$item->title()}</li> {/foreach}{else} <p>No items available.</p>{/if}
{* Check user permissions *}{if $canEdit} <a href="edit.php?id={$item->id()}">Edit</a>{/if}
{if $isAdmin} <a href="delete.php?id={$item->id()}">Delete</a>{/if}
{* Check module settings *}{if $allowComments} {include file="publisher_comments.tpl"}{/if}
{* Check status *}{if $item->status() == 1} <span class="published">Published</span>{elseif $item->status() == 0} <span class="draft">Draft</span>{/if}Advanced Template Techniques
Section intitulée « Advanced Template Techniques »Include Other Templates
Section intitulée « Include Other Templates »{* Include another template *}{include file="publisher_comments.tpl"}
{* Include with variables *}{include file="publisher_article_preview.tpl" item=$item}
{* Include if exists *}{include file="custom_header.tpl"|default:"header.tpl"}Assign Variables in Template
Section intitulée « Assign Variables in Template »{* Assign variable for later use *}{assign var="articleTitle" value=$item->title()}
{* Use assigned variable *}<h1>{$articleTitle}</h1>
{* Assign complex values *}{assign var="count" value=$items|count}{if $count > 0} <p>Found {$count} articles</p>{/if}Template Filters
Section intitulée « Template Filters »{* Text filters *}{$text|htmlspecialchars} {* Escape HTML *}{$text|strip_tags} {* Remove HTML tags *}{$text|truncate:100:"..."} {* Truncate text *}{$text|upper} {* UPPERCASE *}{$text|lower} {* lowercase *}
{* Date filters *}{$date|date_format:"%Y-%m-%d"} {* Format date *}{$date|date_format:"%l, %F %j, %Y"} {* Full format *}
{* Number filters *}{$number|string_format:"%.2f"} {* Format number *}{$number|number_format} {* Add separators *}
{* Array filters *}{$array|implode:", "} {* Join array *}{$array|count} {* Count items *}Debugging Templates
Section intitulée « Debugging Templates »Display Smarty Variables
Section intitulée « Display Smarty Variables »For debugging (remove in production):
{* Show variable value *}<pre>{$variable|print_r}</pre>
{* Show all available variables *}<pre>{$smarty.all|print_r}</pre>
{* Check if variable exists *}{if isset($variable)} Variable exists{/if}
{* Display debug info *}{if $debug} Item: {$item->id()}<br> Title: {$item->title()}<br> Category: {$item->categoryId()}<br>{/if}Enable Debug Mode
Section intitulée « Enable Debug Mode »In /modules/publisher/xoops_version.php or admin settings:
// Enable debugdefine('PUBLISHER_DEBUG', true);Template Migration
Section intitulée « Template Migration »From Old Publisher Version
Section intitulée « From Old Publisher Version »If upgrading from older version:
- Compare old and new template files
- Merge custom changes
- Use new variable names
- Test thoroughly
- Backup old templates
Upgrade Path
Section intitulée « Upgrade Path »Old template New template Actionpublisher_item.tpl → publisher_item.tpl Merge customizationspublisher_cat.tpl → publisher_category.tpl Rename, mergeblock_latest.tpl → publisher_block_latest.tpl Rename, checkBest Practices
Section intitulée « Best Practices »Template Guidelines
Section intitulée « Template Guidelines »✓ Keep business logic in PHP, display logic in templates✓ Use meaningful CSS class names✓ Comment complex sections✓ Test responsive design✓ Validate HTML output✓ Escape user data✓ Use semantic HTML✓ Keep templates DRY (Don't Repeat Yourself)Performance Tips
Section intitulée « Performance Tips »✓ Minimize database queries in templates✓ Cache compiled templates✓ Lazy load images✓ Minify CSS/JavaScript✓ Use CDN for assets✓ Optimize images✗ Avoid complex Smarty logicRelated Documentation
Section intitulée « Related Documentation »- API Reference
- Hooks and Events
- Configuration
- Article Creation
Resources
Section intitulée « Resources »#publisher #templates #smarty #customization #themeing #xoops