Skip to content

Instantly share code, notes, and snippets.

@iiic
Last active November 2, 2016 09:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iiic/97599ee45f2b354a9110cb6c80e039ce to your computer and use it in GitHub Desktop.
Save iiic/97599ee45f2b354a9110cb6c80e039ce to your computer and use it in GitHub Desktop.
Latte snippet pro vkládání zdrojů (externích i interních), jako jsou obrázky, css, javascripty, favikonky, … . Funkční na Nette 2.4.
{spaceless}
{default $type = NULL} {* pokud na nic lepšího nepřijdu, tak zobrazím jako obrázek *}
{default $integrityCheckHash = NULL} {* @todo : pokud někdo zadá integritu atributem integrity="sha256-…něco…" tak bych to měl asi vyseparovat a vložit semka *}
{default $calcIntegrity = TRUE}
{default $noCache = FALSE}
{default $attributes = []}
{default $hashName = $context->parameters[site][security][integrityCheckHash]} {* třeba sha256 *}
{default $appendix = NULL}
{default $forceSpace = ' '} {* "\n" se dá třeba ještě použít *}
{var $fragment = \Nette\Utils\Strings::replace($source, '~^'.$basePath.'/?~i', '')} {* základní část url adresy (celá, pokud jde o externí zdroj) *}
{cache $fragment, if => !$noCache, tags => [sourceLoader]}
{if !$type} {* 1. Zjistím si typ souboru *}
{if \Nette\Utils\Strings::match($fragment, '~^(http|https|ftp)?:?//.+~')} {* externí zdroj (cdn, …) *}
{var $mimeTypeString = get_headers($source, 1)['Content-Type']} {* funkce \mime_content_type() se tu použít nedá… neumí vzdálené soubory *}
{php $attributes[] = 'crossorigin="anonymous"'} {* nepřenáší se cookies - (naneštěstí) funguje POUZE na cizí doméně *}
{var $mimeTypeParts = explode(';', $mimeTypeString)} {* bacha na to mezeru, která se to může snadno vyskytnout před či za textem *}
{if preg_grep('~^\s*text/css\s*$~i', $mimeTypeParts)}
{var $type = 'css'}
{if \Nette\Utils\Strings::contains($source, '//fonts.googleapis.com/css')} {* google fonts vrací různé formáty fontů podle user agenta, z toho důvodu nejde vypočítat integrity check hash *}
{var $calcIntegrity = FALSE}
{/if}
{elseif FALSE} {* @todo : doplnit další mime typy *}
{/if}
{if !$integrityCheckHash && $calcIntegrity && ($type == 'css' || $type == 'script')}
{var $integrityCheckHash = $hashName.'-'.base64_encode(hash($hashName, file_get_contents($source), TRUE))} {* 'nette.safe://' zdá se pro vzdálené soubory nelze použít *}
{/if}
{else} {* lokální zdroj *}
{var $mimeType = mime_content_type($fragment)} {* funkce \mime_content_type() na windows vyžaduje mít v Apachi modul php_fileinfo.dll (nebo na linuxu to je fileinfo.so) *}
{if $mimeType != 'text/plain' && $mimeType != 'text/html'} {* mime typy *}
{if $mimeType == 'application/javascript'}
{var $type = 'script'}
{elseif $mimeType == 'image/x-icon'} {* favikona *}
{var $type = 'favicon'}
{elseif $mimeType == 'application/css'}
{var $type = 'css'}
{/if}
{elseif preg_grep('~^\s*(width|height)\s*=~i', $attributes)} {* tyhle atributy jsou dovoleny pouze u obrázků (NE u favikony) a iframe (které sourceLoader neumí) … takže je to tímto jasné *}
{$type = 'image'}
{* @todo : zkusit, jestli atributy async a defer mohou být je n scriptů a pokud tomu tak skutečně je, tak podle nich scripty identifikovat *}
{elseif $extension = \Nette\Utils\Strings::match($fragment, '~.+\.(js|css)(\?.*)*$~i')} {* přípony souborů *}
{if $extension[1] == 'js'} {* javascript *}
{var $type = 'script'}
{else} {* css *}
{var $type = 'css'}
{/if}
{else} {* cesta, doména, … *}
{/if}
{if !$integrityCheckHash && $calcIntegrity && ($type == 'css' || $type == 'script')}
{var $integrityCheckHash = $hashName.'-'.base64_encode(hash($hashName, file_get_contents('nette.safe://'.$context->parameters[wwwDir].'/'.$fragment), TRUE))}
{/if}
{if !$appendix}
{var $appendix = \Nette\Utils\Strings::contains($source, '?')?'&':'?'.base_convert($noCache?time():filemtime('nette.safe://'.$context->parameters[wwwDir].'/'.$fragment), 10, 36)} {* \base_convert() je převod mezi libovolnými číselnými soustavami, kde 36 je maximální možný základ *}
{/if}
{/if}
{/if}
{if $type == 'favicon'} {* 2. pokud schází, tak doplním poviné atributy a přidám nějaké nepoviné, ale důležité atributy *}
{var $type = 'link'}
{if !preg_grep("~^\s*rel\s*=\s*(\"|')\s*(shortcut|.*\s*shortcut|shortcut\s*.*|icon|.*\s*icon|icon\s*.*)\s*(\"|')\s*$~", $attributes)}
{php $attributes[] = 'rel="shortcut icon"'}
{/if}
{elseif $type == 'link'}
{* nenapadá mě, co dělat … zatím *}
{elseif $type == 'css'}
{var $type = 'link'} {* nyní už na tom nezáleží, tak si to můžu zjednodušit *}
{if $integrityCheckHash}
{php $attributes[] = 'integrity="'.$integrityCheckHash.'"'}
{/if}
{if !preg_grep("~^\s*rel\s*=\s*(\"|')\s*(stylesheet|.*\s*stylesheet|stylesheet\s*.*)\s*(\"|')\s*$~", $attributes)}
{php $attributes[] = 'rel="stylesheet"'}
{/if}
{elseif $type == 'script'}
{if $integrityCheckHash}
{php $attributes[] = 'integrity="'.$integrityCheckHash.'"'}
{/if}
{else} {* jinak jde o obrázek… *}
{var $calcIntegrity = FALSE} {* u obrázků nemá žádný vliv… vyzkoušeno *}
{if !(preg_grep('~^\s*width\s*=~i', $attributes) || preg_grep('~^\s*height\s*=~i', $attributes))}
{var $image = \Nette\Utils\Image::fromFile('nette.safe://'.$context->parameters[wwwDir].'/'.$fragment)}
{php $attributes[] = 'width="'.$image->width.'"'}
{php $attributes[] = 'height="'.$image->height.'"'}
{/if}
{if !preg_grep('~^\s*alt\s*=~i', $attributes)}
{php $attributes[] = 'alt="obrázek '.$fragment.'"'}
{/if}
{/if}
{if $type == 'script'} {* 3. Vytvořím kód načítající tento zdroj - buď javascript *}
<script
src="{$source.$appendix|noescape}"{$forceSpace|noescape}
{implode($forceSpace, $attributes)|noescape}
></script>
{elseif $type == 'link'} {* link (css, favicon, …) *}
<link
href="{$source.$appendix|noescape}"{$forceSpace|noescape} {*{\Nette\Utils\Strings::contains($source, '?')?'&':'?'}{base_convert($noCache?time():filemtime('nette.safe://'.$context->parameters[wwwDir].'/'.$fragment), 10, 36)}*}
{implode($forceSpace, $attributes)|noescape}
>
{else} {* jinak obrázek *}
<img
src="{$source.$appendix|noescape}"{$forceSpace|noescape} {*{\Nette\Utils\Strings::contains($source, '?')?'&':'?'}{base_convert($noCache?time():filemtime('nette.safe://'.$context->parameters[wwwDir].'/'.$fragment), 10, 36)}*}
{implode($forceSpace, $attributes)|noescape}
{* {$forceSpace|noescape}ismap {* pokud je obrázek uvnitř odkazu, tak se při kliku na obrázek doplní i přesné souřadnice pixelu v obrázku, na který bylo kliknuto *}
{* longdesc="…" {* url adresa, na které je dlouhý popisek obrázku a co je důležité… může obsahovat i hash na záložku na stejné stránce, jako je obrázek, nebo odkaz a hash *}
>
{/if}
{/cache}
{/spaceless}
@iiic
Copy link
Author

iiic commented Nov 2, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment