[addon webloader] Extras/webloader
- 2bfree
- Člen | 248
uestla napsal(a):
Např. takhdlenc:
$css = new CssLoader(); if (Environment::isProduction()) { $css->filters[] = array($this, 'packCss'); }
ad komprimace výstupního HTML – použij např. helper TemplateHelpers::strip().
Asi jsem hloupý, ale v readme je:
<?php
protected function createComponentCss() {
$css = new WebLoader\CssLoader;
$css->sourcePath = WWW_DIR.DS."css";
$css->tempPath = WWW_DIR.DS."webtemp";
$css->tempUri = ((isset($_SERVER["HTTPS"]))&&($_SERVER["HTTPS"]!=""))? "https://".$_SERVER["SERVER_NAME"]."/webtemp" : "http://".$_SERVER["SERVER_NAME"]."/webtemp";
$css->filters[] = function ($code) {
return cssmin::minify($code, array("remove-last-semicolon"=>TRUE));
};
return $css;
}
?>
upravil jsem to na:
<?php
protected function createComponentCss() {
$css = new WebLoader\CssLoader;
$css->sourcePath = WWW_DIR.DS."css";
$css->tempPath = WWW_DIR.DS."webtemp";
$css->tempUri = ((isset($_SERVER["HTTPS"]))&&($_SERVER["HTTPS"]!=""))? "https://".$_SERVER["SERVER_NAME"]."/webtemp" : "http://".$_SERVER["SERVER_NAME"]."/webtemp";
if(Nette\Environment::getName()=="production"){
$css->filters[] = function ($code) {
return cssmin::minify($code, array("remove-last-semicolon"=>TRUE));
};
}
return $css;
}
?>
A na Development prostředí mám vygenerováno
<?php
<link rel="stylesheet" type="text/css" href="http://test.localhost/webtemp/cssloader-f6aef36945a5-screen.css?1290956224" />
?>
namísto očekávaného
<?php
<link rel="stylesheet" type="text/css" href="http://test.localhost/css/screen.css" />
?>
ad komprimace výstupního HTML mi vadí to, že tomu musím upravit generování šablon tak, že v @layout.phtml musím mít jenom
<?php
@{include content|strip}
?>
Tedy nemohu použít @layout.phtml pro layout jako takový
- uestla
- Backer | 799
Tak můžeš si buď stejně jako komprimaci nastavit public proměnnou
Webloader::$joinFiles
,
$css = new CssLoader();
if (Environment::isProduction()) {
$css->joinFiles = FALSE;
}
nebo přímo v šabloně používat WebLoader jen při production módu…
{if Environment::isProduction()}
{widget css 'style.css'}
{else}
<link rel="stylesheet" type="text/css" href="{$basePath}/css/style.css">
{/if}
No a ten helper TemplateHelpers::strip()
můžeš de facto
použít i jako filtr…
// BasePresenter...
public function templatePrepareFilters($template)
{
parent::templatePrepareFilters($template);
$template->registerFilter('TemplateHelpers::strip');
}
- 2bfree
- Člen | 248
Tak můžeš si buď stejně jako komprimaci nastavit public proměnnou
Webloader::$joinFiles
,$css = new CssLoader(); if (Environment::isProduction()) { $css->joinFiles = FALSE; }
nebo přímo v šabloně používat WebLoader jen při production módu…
{if Environment::isProduction()} {widget css 'style.css'} {else} <link rel="stylesheet" type="text/css" href="{$basePath}/css/style.css"> {/if}
Tohle neřeší přesně to co jsem chtěl, ale děkuji za tip. Nakonec jsem to vyřešil následovně:
továrnička v presenteru:
<?php
protected function createComponentCss() {
$css = new WebLoader\CssLoader;
$css->sourcePath = WWW_DIR.DS."css";
$css->sourceUri = ((isset($_SERVER["HTTPS"]))&&($_SERVER["HTTPS"]!=""))? "https://".$_SERVER["SERVER_NAME"]."/webtemp" : "http://".$_SERVER["SERVER_NAME"]."/css";
$css->tempPath = WWW_DIR.DS."webtemp";
$css->tempUri = ((isset($_SERVER["HTTPS"]))&&($_SERVER["HTTPS"]!=""))? "https://".$_SERVER["SERVER_NAME"]."/webtemp" : "http://".$_SERVER["SERVER_NAME"]."/webtemp";
if(Nette\Environment::getName()=="production"){
$css->filters[] = function ($code) {
return cssmin::minify($code, array("remove-last-semicolon"=>TRUE));
};
} elseif(Nette\Environment::getName()=="development"){
$css->joinFiles = FALSE;
}
return $css;
}
?>
Upravil jsem webloader tak, že jsem přidal proměnou sourceUri a upravil jsem metodu render() následovně:
<?php
public function render() {
$hasArgs = func_num_args() > 0;
if ($hasArgs) {
$backup = $this->files;
$this->clear();
$this->addFiles(func_get_args());
}
// joined files
if ($this->joinFiles) {
$file = $this->generate($this->files);
echo $this->getElement($this->tempUri . "/" . $file);
// separated files
} else {
foreach ($this->files as $file) {
if(\Nette\Environment::getName()=="development"){
echo $this->getElement($this->sourceUri . "/" . \str_replace($this->sourcePath.DS,"",$file));
} else {
$file = $this->generate(array($file));
echo $this->getElement($this->tempUri . "/" . $file);
}
}
}
if ($hasArgs) {
$this->files = $backup;
}
}
?>
výsledek je takový, že na produkčním prostředí se ty soubory všechny sloučí do jednoho a na vývojovém se použijí výchozí soubory ze sourcePath
No a ten helper
TemplateHelpers::strip()
můžeš de facto použít i jako filtr…// BasePresenter... public function templatePrepareFilters($template) { parent::templatePrepareFilters($template); $template->registerFilter('TemplateHelpers::strip'); }
Díky, na tohle se podívám
- Honza Marek
- Člen | 1664
defaultně webloader nemůže zohledňovat k cestě do vygenerovaného souboru jazyk, ale určitě by šla ta třída podědit, aby se to dělo.
- Honza Marek
- Člen | 1664
Atribut media se dá nastavit, ale musíš potom mít dvě komponenty (printCss, screenCss).
- Michalek
- Člen | 211
Osobně to dělám takhle, jak píše Honza.
<?php
protected function createComponentCss()
{
$css = new CssLoader;
$css->media = 'screen, projection';
// ... nastavení ...
return $css;
}
protected function createComponentCssPrint()
{
$css = clone $this['css'];
$css->media = 'print';
return $css;
}
?>
Editoval Michalek (30. 1. 2011 16:50)
- whipster
- Člen | 17
Prosím o radu, URL v CSS se mi absolutizuje špatně
viz
http://localhost/Dispecinkpco/www%0Csssmoothnessimages/ui-bg_glass_75_e6e6e6_1x400.png
mělo by to být
http://localhost/Dispecinkpco/www/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
nemám žádní filtry , nejnovější verzi z GITHuB
používám nejnovější verzi Nette 2.0 Alpha 5.3 Nighty builds
Editoval whipster (13. 2. 2011 17:27)
- lutor
- Člen | 27
Zdravím, chtěl bych požádat o radu, jak doplnit regulár v
CssUrlFilter.php
ve funkci __invoke
tak, aby nežral
DataUri (např. v CSS mám url('data:image/png;base64,...
), což
filter vezme, a snaží se to zpracovat. Ve finále to dopadne tak, že soubor
není zpracován a místo toho je vrácen null
(bug?).
Konkrétně se jedná o regexp
$regexp = '~
(?<![a-z])
url\( ## url(
\s* ## optional whitespace
([\'"])? ## optional single/double quote
( (?: (?:\\\\.)+ ## escape sequences
| [^\'"\\\\,()\s]+ ## safe characters
| (?(1) (?!\1)[\'"\\\\,() \t] ## allowed special characters
| ^ ## (none, if not quoted)
)
)* ## (greedy match)
)
(?(1)\1) ## optional single/double quote
\s* ## optional whitespace
\) ## )
~xs';
- kravčo
- Člen | 721
Upraviť by to šlo tak, že to odignoruje všetky URL začínajúce na
data:
:
$regexp = '~
(?<![a-z])
url\( ## url(
\s* ## optional whitespace
([\'"])? ## optional single/double quote
( (?!data:) ## ignore urls starting with `data:`
(?: (?:\\\\.)+ ## escape sequences
| [^\'"\\\\,()\s]+ ## safe characters
| (?(1) (?!\1)[\'"\\\\,() \t] ## allowed special characters
| ^ ## (none, if not quoted)
)
)* ## (greedy match)
)
(?(1)\1) ## optional single/double quote
\s* ## optional whitespace
\) ## )
~xs';
Ale treba povedať, že tento regulár by si zaslúžil zrefaktorovať, lebo efektivitou zrovna neoplýva :)
- zarubik
- Člen | 31
Prosím jak přidáváte další JS a CSS z dalších komponent?
Tak abych v layoutu mohl v <head> {control js} a {control css}.
V komponentě bych to chtěl mít v render(), tak abych mohl využívát i jiné rendry, než defaultní.
A pak se stává to, že komponenty, které se volají v <body> už se
nepřidají javascripty a styly.
Funguje to pouze, když volání komponent dám až před </body>.
Zkoušel jsem obalit do bloku a includnout na začátku šabolny, ale pak se mi zobrazí 2× … kdyz definuju block pres „define“ tak se zase nacte az pri rendrovani v hlavicce :D
Snad jsem to napsal trosku srozumitelne. Diky za info, jak to pouzivate :)
- Aurielle
- Člen | 1281
Nedávej to do render ale nejlépe do metody attached(), nějak takto:
protected function attached($presenter)
{
parent::attached($presenter);
if($presenter instanceof Nette\Application\UI\Presenter) { // Komponenta může být připojena i k jiné komponentě, nejen k presenteru
$presenter['css']->addFiles(array(...));
$presenter['js']->addFiles(array(...));
}
}
- Kurtas
- Člen | 109
Ahoj,
V poslední verzi (1.1) již neexistují tyto vlastnosti
$cssLoader->sourceUri a $cssLoader->absolutizeUrls
Hlásí mi to vyjímku
Cannot write to an undeclared property WebLoader\CssLoader::$sourceUri
Nevím jestli by to vúbec pomohlo, ale špatně mi to upravuje cestu k obrázkům v css např
background: url('/ndibi/www/\css\../images/datagrid/icons/find.png') no-repeat right center;
Správně by mělo být
background: url('/ndibi/www/css/../images/datagrid/icons/find.png') no-repeat right center;
CssLoader mám nastaven takto:
$css = $header['css'];
$css->sourcePath = WWW_DIR . '/css';
$css->tempUri = $this->getHttpRequest()->url->baseUrl . 'temp';
$css->tempPath = WWW_DIR . '/temp';
Díky za pomoc
- 2bfree
- Člen | 248
Stáhl jsem nejnovější Nette a pokusil se do něj implementovat webloader.
do config.neon jsem přidal následující
services:
robotLoader:
option:
directory: [%appDir%, %libsDir%]
run: true
Do BasePresenter.php jsem dal následující
<?php
abstract class BasePresenter extends Nette\Application\UI\Presenter {
protected function createComponentCss() {
$css = new WebLoader\CssLoader;
// cesta na disku ke zdroji
$css->sourcePath = $this->getContext()->params['wwwDir'].DIRECTORY_SEPARATOR."css";
// cesta na webu ke zdroji (kvůli absolutizaci cest v css souboru)
//$css->sourceUri = $this->getHttpRequest()->url->baseUrl."css";
// cesta na webu k cílovému adresáři
$css->tempUri = $this->getHttpRequest()->url->baseUrl."webtemp";
// cesta na disku k cílovému adresáři
$css->tempPath = $this->getContext()->params['wwwDir'].DIRECTORY_SEPARATOR."css";
// nastavení atributu media
$css->media = 'screen, projection';
return $css;
}
}
?>
Narazil jsem na následující problémy:
- musel jsem zakomentovat nastavení atributů sourceUri jinak mám ten samý problém jako ostatní
- Vrací mi to chybu:
Use of undefined constant WWW_DIR – File: CssUrlsFilter.php Line: 28
Co se bodu 2 týče, vyřešeno nahrazením
<?php
$docroot = realpath(WWW_DIR);
?>
za
<?php
$docroot = realpath(Environment::getContext()->params['wwwDir']);
?>
Editoval 2bfree (9. 11. 2011 10:39)
- 2bfree
- Člen | 248
@kurtas @jack06: Co se absolutizace url v css týče, tak chyba je v souboru /libs/Extras/Webloader/filters/CssUrlsFilter.php kde na řádku 41 je zakomentován řádek, který je třeba odkomentovat
<?php
$path = self::cannonicalizePath($path);
?>
Dále doporučuji zaměnit v tom samém souboru regulární výraz za ten, který píše @kravčo
- Tomáš Votruba
- Moderator | 1114
Mám takový problém, věřím, že je to nějaká prkotina.
- Plugin na slideshow + skript níže uvedený, které načítám přes
<script src=...
v pořádku fungují. {control js "jquery/jquery.bxSlider.min.js"}
+ skritp níže uvedený načítaný přes<script src=...
také funguje{control js "jquery/jquery.bxSlider.min.js", "scripts.unlogged.js"}
už nefunguje
Kde by mohla být chybka?
<script>
$(document).ready(function() {
var screenshow = $('#screenshow').bxSlider({
mode: 'fade',
auto: 'true',
pause: 5000,
controls: 'false',
infiniteLoop: 'true',
randomStart: 'true'
});
$('#go-prev').click(function(){
screenshow.goToPreviousSlide();
return false;
});
$('#go-next').click(function(){
screenshow.goToNextSlide();
return false;
});
});
</script>
Díky.
- 2bfree
- Člen | 248
Docela zajímavá technologie pro optimalizaci načítání javascriptu. Mohlo by stát za prozkoumání pro případné další využití.
- Nox
- Člen | 378
http://microjs.com/#… atd. … nevim jestli má někdo zkušenosti s více a může to porovnat
- 2bfree
- Člen | 248
Probírám se teď optimalizací rychlosti načítání webu dle google page
speed.
Uvažovali jste o tom, že by výstup JS componenty byl podle následujícího
doporučení?
http://code.google.com/…ocs/rtt.html#…
- 2bfree
- Člen | 248
Jinak mluvím o úpravě kódu v JavaScriptLoader.php
<?php
/**
* Get script element
* @param string $source
* @return Html
*/
public function getElement($source) {
//return Html::el("script")->type("text/javascript")->src($source);
return Html::el("script")->type("text/javascript")->setText("
var node = document.createElement('script');
node.type = 'text/javascript';
node.async = true;
node.src = '$source';
document.body.appendChild(node);
");
}
?>
- mcmatak
- Člen | 504
css a js obvykle zkládám z desítek souborů, obecné css pro flashes, obecné js pro notify, netteform, atd.
vzhledem k tomu, že filemtime a fileexist je dost drahá operace, nemáte někdo tip jak tomu ulehčit než aby to 30 s každým req. checkovalo filemtime?
alespon to zkrátit na 5 minutový úsek, ale nevím jak, jedine název souboru složený ze všech cest použitých souborů jeho md5 a uvnitř na prvním řádku poslední check, pokud nebude starší než 15min dejme tomu, tak nebudeme checkovat ostatní filemtime
má někdo lepší nápad? nebo způsob jak tohle provést?
- Honza Marek
- Člen | 1664
Začal jsem upravovat WebLoader tak, aby obstál v 21. století. K vidění je náhled na https://github.com/…e/webloader2. Je tam i readme, ze kterého se dá vykoukat nový způsob použití.
Co je nového:
- unit testy
- oku objektového programátora více lahodící kód
- lepší rozšiřitelnost – jde snadněji vyměnit třeba pojmenování výsledného souboru
- CSS urls filter je deprecated, protože s ním byly jen problémy (ale možná už nebudou, když jsou na něj napsané testy)
- WebLoader je teoreticky schopný fungovat i bez Nette. Na Nette jsou závislé jen controly, co umí vypsat html tagy načítající kompilované soubory.
- třídy Webloader\Compiler lze umístit do config.neon jako službu a následně je snadné např. generovat CSS v deploy scriptu ($container->cssLoader->generate())
- časem bych se možná kouknul na možnosti nette rozšíření pro snadné nastavování css a js už v config.neon
Uvítám nějakou podnětnou odezvu (kromě stížností na nedodržení zpětné kompatibility ;) ). Nicméně není to zatím hotové. Funguje to, na co jsou testy.
- Tomáš Votruba
- Moderator | 1114
Skvělá práce, Honzo. Díky!
V doplňcích to taky ještě updatneš?
E: Ještě mne napadlo, že by se v úvodním příspěvku hodil link na uvedení 2.0 – https://forum.nette.org/…as-webloader?p=7
Editoval Schmutzka (14. 2. 2012 16:09)
- davidm
- Člen | 81
ještě k tomu url filtru, nešel by ten regulár nahradit timhle? btw určitě je škoda ho dávat deprecated, je to šikovná věc
- Honza Marek
- Člen | 1664
Přímo s tím regulárem snad problémy nikdy nebyly, spíš se zbytkem filtru. Přijde ti ten z asseticu v něčem lepší?
Že je CssUrlsFilter teď deprecated znamená, že ho nepoužívám a není výchozí. Kdokoliv jinej klidně může. Mazat ho nebudu a když mi někdo potvrdí, že s nim nejsou problémy, tak klidně můžu to deprecated zase sundat.
- Ivorius
- Nette Blogger | 119
Jak mohu ten CssUrlsFilter použít? Koukal jsem do té třídy a
__invoke($code, \WebLoader\Compiler $loader, $file = null)
. Co mám
tedy předat v tom $code?
Zatím mám
$compiler = WebLoader\Compiler::createCssCompiler($files, WWW_DIR . '/webtemp');
$fil = new WebLoader\Filter\CssUrlsFilter(WWW_DIR, $this->template->basePath);
$compiler->addFilter($fil($code, $compiler));
Nebo případně máte jiný nápad, jak vyřešit cesty k background-url: když mám css v různých složkách?
- Honza Marek
- Člen | 1664
Předej jen $fil. Nebo můžeš psát ty CSS tak, že počítají s tím, že leží ve složce webtemp.
- Honza Marek
- Člen | 1664
To bude pořád fungovat. Ale nepovažuju to úplně za šťastný, protože se ti může generovat pro každou stránku jiný CSS, které se bude lišit několika řádkama CSS komponenty. Nebo dokonce jen pořadím CSS z komponent ve vygenerovaném CSS.
- Matúš Matula
- Člen | 257
Ahoj,
nechces pridat gettery a settery do Webloaderu pre $compiler a $tempPath? Pouzivam Webloader na nacitavanie css a js napriec celou aplikaciou, kedy potrebujem menit fileCollection $compiler-u a vysledok ukladat do istej struktury, a teda menit aj $tempPath. Vyhol by som sa tak ‚zbytocnemu‘ instanciovaniu.
- Honza Marek
- Člen | 1664
WebLoader umí novej trik:
$files->addFiles(Finder::findFiles('*.css')->from(APP_DIR . '/templates'));
- Tomáš Votruba
- Moderator | 1114
Honza Marek napsal(a):
WebLoader umí novej trik:
$files->addFiles(Finder::findFiles('*.css')->from(APP_DIR . '/templates'));
Super, díky!
- Honza Marek
- Člen | 1664
Knihovnu WebLoader lze načítat přes package manager Composer – http://packagist.org/…ek/WebLoader