Nette Assets
V-ați săturat să gestionați manual fișierele statice în aplicațiile dumneavoastră web? Uitați de codificarea manuală a căilor, de gestionarea invalidării cache-ului sau de îngrijorarea legată de versionarea fișierelor. Nette Assets transformă modul în care lucrați cu imagini, foi de stil, scripturi și alte resurse statice.
- Versionare inteligentă asigură că browserele încarcă întotdeauna cele mai recente fișiere
- Detecție automată a tipurilor și dimensiunilor fișierelor
- Integrare perfectă cu Latte cu tag-uri intuitive
- Arhitectură flexibilă care suportă sisteme de fișiere, CDN-uri și Vite
- Încărcare leneșă pentru performanță optimă
De ce Nette Assets?
Lucrul cu fișiere statice înseamnă adesea cod repetitiv, predispus la erori. Construiți manual URL-uri, adăugați parametri de versiune pentru invalidarea cache-ului și gestionați diferit tipurile de fișiere. Acest lucru duce la cod de genul:
<img src="/images/logo.png?v=1699123456" width="200" height="100" alt="Logo">
<link rel="stylesheet" href="/css/style.css?v=2">
Cu Nette Assets, toată această complexitate dispare:
{* Totul automatizat - URL, versionare, dimensiuni *}
<img n:asset="images/logo.png">
<link n:asset="css/style.css">
{* Sau pur și simplu *}
{asset 'css/style.css'}
Asta e tot! Biblioteca automat:
- Adaugă parametri de versiune bazat pe timpul de modificare al fișierului
- Detectează dimensiunile imaginii și le include în HTML
- Generează elementul HTML corect pentru fiecare tip de fișier
- Gestionează atât mediile de dezvoltare, cât și cele de producție
Instalare
Instalați Nette Assets folosind Composer:
composer require nette/assets
Necesită PHP 8.1 sau o versiune superioară și funcționează perfect cu Nette Framework, dar poate fi folosit și independent.
Primii Pași
Nette Assets funcționează imediat, fără configurare. Plasați fișierele statice în directorul www/assets/
și începeți să le utilizați:
{* Afișează o imagine cu dimensiuni automate *}
{asset 'logo.png'}
{* Include o foaie de stil cu versionare *}
{asset 'style.css'}
{* Încarcă un modul JavaScript *}
{asset 'app.js'}
Pentru mai mult control asupra HTML-ului generat, utilizați atributul n:asset
sau funcția
asset()
.
Cum Funcționează
Nette Assets este construit în jurul a trei concepte cheie care îl fac puternic, dar simplu de utilizat:
Asset-uri – Fișierele Dumneavoastră Făcute Inteligente
Un asset reprezintă orice fișier static din aplicația dumneavoastră. Fiecare fișier devine un obiect cu proprietăți utile, doar pentru citire:
$image = $assets->getAsset('photo.jpg');
echo $image->url; // '/assets/photo.jpg?v=1699123456'
echo $image->width; // 1920
echo $image->height; // 1080
echo $image->mimeType; // 'image/jpeg'
Diferite tipuri de fișiere oferă proprietăți diferite:
- Imagini: lățime, înălțime, text alternativ, încărcare leneșă
- Scripturi: tip modul, hash-uri de integritate, crossorigin
- Foi de stil: interogări media, integritate
- Audio/Video: durată, dimensiuni
- Fonturi: preîncărcare corectă cu CORS
Biblioteca detectează automat tipurile de fișiere și creează clasa de asset corespunzătoare.
Mapperi – De unde provin fișierele
Un mapper știe cum să găsească fișiere și să creeze URL-uri pentru ele. Puteți avea mai mulți mapperi pentru diferite scopuri – fișiere locale, CDN, stocare în cloud sau instrumente de construire (fiecare dintre ele are un nume). FilesystemMapper-ul încorporat gestionează fișierele locale, în timp ce ViteMapper se integrează cu instrumente moderne de construire.
Mapperii sunt definiți în Configurare.
Registrul – Interfața dumneavoastră principală
Registrul gestionează toți mapperii și oferă API-ul principal:
// Injectați registrul în serviciul dumneavoastră
public function __construct(
private Nette\Assets\Registry $assets
) {}
// Obțineți asset-uri de la diferiți mapperi
$logo = $this->assets->getAsset('images:logo.png'); // mapper 'image'
$app = $this->assets->getAsset('app:main.js'); // mapper 'app'
$style = $this->assets->getAsset('style.css'); // utilizează mapper-ul implicit
Registrul selectează automat mapper-ul potrivit și memorează în cache rezultatele pentru performanță.
Lucrul cu Asset-uri în PHP
Registrul oferă două metode pentru recuperarea asset-urilor:
// Aruncă Nette\Assets\AssetNotFoundException dacă fișierul nu există
$logo = $assets->getAsset('logo.png');
// Returnează null dacă fișierul nu există
$banner = $assets->tryGetAsset('banner.jpg');
if ($banner) {
echo $banner->url;
}
Specificarea Mapper-ilor
Puteți alege explicit ce mapper să utilizați:
// Utilizează mapper-ul implicit
$file = $assets->getAsset('document.pdf');
// Utilizează mapper-ul specific cu prefix
$image = $assets->getAsset('images:photo.jpg');
// Utilizează mapper-ul specific cu sintaxă de array
$script = $assets->getAsset(['scripts', 'app.js']);
Proprietăți și Tipuri de Asset-uri
Fiecare tip de asset oferă proprietăți relevante, doar pentru citire:
// Proprietăți imagine
$image = $assets->getAsset('photo.jpg');
echo $image->width; // 1920
echo $image->height; // 1080
echo $image->mimeType; // 'image/jpeg'
// Proprietăți script
$script = $assets->getAsset('app.js');
echo $script->type; // 'module' or null
// Proprietăți audio
$audio = $assets->getAsset('song.mp3');
echo $audio->duration; // duration in seconds
// Toate asset-urile pot fi convertite la șir (returnează URL)
$url = (string) $assets->getAsset('document.pdf');
Proprietățile precum dimensiunile sau durata sunt încărcate leneș, doar la accesare, menținând biblioteca rapidă.
Utilizarea Asset-urilor în Șabloanele Latte
Nette Assets oferă o integrare intuitivă cu Latte prin tag-uri și funcții.
{asset}
Tag-ul {asset}
randează elemente HTML complete:
{* Randează: <img src="/assets/hero.jpg?v=123" width="1920" height="1080"> *}
{asset 'hero.jpg'}
{* Randează: <script src="/assets/app.js?v=456" type="module"></script> *}
{asset 'app.js'}
{* Randează: <link rel="stylesheet" href="/assets/style.css?v=789"> *}
{asset 'style.css'}
Tag-ul automat:
- Detectează tipul asset-ului și generează HTML-ul corespunzător
- Include versionare pentru invalidarea cache-ului
- Adaugă dimensiuni pentru imagini
- Setează atributele corecte (tip, media, etc.)
Când este utilizat în interiorul atributelor HTML, acesta afișează doar URL-ul:
<div style="background-image: url({asset 'bg.jpg'})">
<img srcset="{asset 'logo@2x.png'} 2x">
n:asset
Pentru control complet asupra atributelor HTML:
{* Atributul n:asset completează src, dimensiuni etc. *}
<img n:asset="product.jpg" alt="Product" class="rounded">
{* Funcționează cu orice element relevant *}
<script n:asset="analytics.js" defer></script>
<link n:asset="print.css" media="print">
<audio n:asset="podcast.mp3" controls></audio>
Utilizați variabile și mapperi:
{* Variabilele funcționează natural *}
<img n:asset="$product->image">
{* Specificați mapper-ul cu acolade *}
<img n:asset="images:{$product->image}">
{* Specificați mapper-ul cu notație de array *}
<img n:asset="[images, $product->image]">
asset()
Pentru flexibilitate maximă, utilizați funcția asset()
:
{var $logo = asset('logo.png')}
<img src={$logo} width={$logo->width} height={$logo->height}>
{* Sau direct *}
<img src={asset('logo.png')} alt="Logo">
Asset-uri Opționale
Gestionați asset-urile lipsă în mod elegant cu {asset?}
, n:asset?
și tryAsset()
:
{* Tag opțional - nu randează nimic dacă asset-ul lipsește *}
{asset? 'optional-banner.jpg'}
{* Atribut opțional - sare peste dacă asset-ul lipsește *}
<img n:asset?="user-avatar.jpg" alt="Avatar" class="avatar">
{* Cu fallback *}
{var $avatar = tryAsset('user-avatar.jpg') ?? asset('default-avatar.jpg')}
<img n:asset=$avatar alt="Avatar">
{preload}
Îmbunătățiți performanța de încărcare a paginii:
{* În secțiunea <head> *}
{preload 'critical.css'}
{preload 'important-font.woff2'}
{preload 'hero-image.jpg'}
Generează link-uri de preîncărcare adecvate:
<link rel="preload" href="/assets/critical.css?v=123" as="style">
<link rel="preload" href="/assets/important-font.woff2" as="font" crossorigin>
<link rel="preload" href="/assets/hero-image.jpg" as="image">
Funcționalități Avansate
Auto-Detecția Extensiilor
Gestionați automat mai multe formate:
assets:
mapping:
images:
path: img
extension: [webp, jpg, png] # Încearcă în ordine
Acum puteți solicita fără extensie:
{* Găsește automat logo.webp, logo.jpg sau logo.png *}
{asset 'images:logo'}
Perfect pentru îmbunătățirea progresivă cu formate moderne.
Versionare Inteligentă
Fișierele sunt versionate automat pe baza timpului de modificare:
{asset 'style.css'}
{* Ieșire: <link rel="stylesheet" href="/assets/style.css?v=1699123456"> *}
Când actualizați fișierul, timestamp-ul se modifică, forțând reîmprospătarea cache-ului browserului.
Controlați versionarea per asset:
// Dezactivează versionarea pentru un asset specific
$asset = $assets->getAsset('style.css', ['version' => false]);
// În Latte
{asset 'style.css', version: false}
Asset-uri Font
Fonturile beneficiază de un tratament special cu CORS adecvat:
{* Preîncărcare corectă cu crossorigin *}
{preload 'fonts:OpenSans-Regular.woff2'}
{* Utilizați în CSS *}
<style>
@font-face {
font-family: 'Open Sans';
src: url('{asset 'fonts:OpenSans-Regular.woff2'}') format('woff2');
font-display: swap;
}
</style>
Mapperi Personalizați
Creați mapperi personalizați pentru nevoi speciale, cum ar fi stocarea în cloud sau generarea dinamică:
use Nette\Assets\Mapper;
use Nette\Assets\Asset;
use Nette\Assets\Helpers;
class CloudStorageMapper implements Mapper
{
public function __construct(
private CloudClient $client,
private string $bucket,
) {}
public function getAsset(string $reference, array $options = []): Asset
{
if (!$this->client->exists($this->bucket, $reference)) {
throw new Nette\Assets\AssetNotFoundException("Asset '$reference' not found");
}
$url = $this->client->getPublicUrl($this->bucket, $reference);
return Helpers::createAssetFromUrl($url);
}
}
Înregistrați în configurare:
assets:
mapping:
cloud: CloudStorageMapper(@cloudClient, 'my-bucket')
Utilizați ca orice alt mapper:
{asset 'cloud:user-uploads/photo.jpg'}
Metoda Helpers::createAssetFromUrl()
creează automat tipul corect de asset pe baza extensiei fișierului.