Podstrčení jiného obrázku pokud dotazovaný neexistuje
- holantomas
- Člen | 55
Zdravím,
velice jednoduchá věc. Jelikož jsem si tu toho dost přečetl, tak jsem
zjistil, že bych neměl do .htaccess vůbec lést. Takže bych chtěl poprosit
o pomoc s nastavením routeru. A to tak. Pokud napr.
uploads/photos/teachers/1.jpg nebo uploads/photos/students/3.jpg neexistuji, tak
se nahradí prohlížeči podstrčí images/incognito.jpg. O to jaký http kód
odešlě mi nejde může klidně poslat 302(myslím že by to bylo
i lepší).
Zkoušel jsem hodně kombinací a zkončil u téhle.
<?php
public function createRouter()
{
$router = new RouteList();
$router[] = new Route('<presenter>[-<page>]/<action>[/<id>]', 'Homepage:default');
$router[] = new Route('uploads/photos/teachers/<photo>', array(
'presenter' => 'Homepage',
'action' => 'default',
'photo' => 'incognito.jpg'
));
return $router;
}
?>
Problém je v tom, když si otevřu samotný obrázek co existuje např. http://neco.cz/…achers/1.jpg tak URl zůstane stejná a obrázek se zobrazí. Ale když dám např. http://neco.cz/…achers/2.jpg, (tento obrázek neexistuje) tak se mi zobrazí hlavní stránka a a URL se změní na http://neco.cz/?… a já chci http://neco.cz/…ncognito.jpg
- MartinitCZ
- Člen | 580
Tohle nemá v routě co dělat.
Přesun logiku do akce:
function actionDefault($photo)
{
....
if (file_exists($file = SLOZKA_FOTEK . '/' . $photo)) {
return $file;
} else {
return SLOZKA_FOTEK . '/incognito.jpg';
}
....
}
- holantomas
- Člen | 55
Tak to se omlouvám, ale to je podle mě blbost. Proč kopírovat stejný kód 20× když můžu v .htaccess napsat jeden řádek ? Tomuhle přesně jsem se chtěl vyhnout.
- enumag
- Člen | 2118
Moje představa je přibližně následující:
- všechny obrázky budou v jedné složce (nebo několika málo složkách), např. /upload
- pokud obrázek existuje tak se prostě zobrazí, Nette se vůbec nedostane ke slovu (nelze použít v případech kdy je vyžadována autorizace pro zobrazení obrázku)
- pokud obrázek neexistuje, odchytne to přibližně takováhle routa:
$router[] = new Route('uploads/<photo .+>', array(
'presenter' => 'Images',
'action' => 'default'
));
Presenter pak dle parametru photo rozezná jaké rozměry má obrázek mít
(to by se dalo řešit už v route a presenter by dostal
$dimensions
či $width
a $height
) a
vrátí výchozí obrázek v potřebných rozměrech, případně na něj
přesměruje pomocí redirectUrl (sám nevím která možnost je lepší –
zda vrátit rovnou nebo přesměrovat).
Editoval enumag (30. 9. 2013 17:33)
- holantomas
- Člen | 55
Nad tím vytvořit čistý presenter pro zobrazení obrázku jsem taky přemýšlel … a zatím se to jeví jako nejlepší nápad
- frosty22
- Člen | 373
Jo a jenom alternative – né vždy to jde, záleží oč se přímo snažíš, ale občas je hezčí toto řešit přes JS/CSS. Minimálně je to méně náročné na server, pokud se jedná o zatíženější web, či pokud se jedná o vyšší množství obrázků, které nemusí existovat.
Buď přes CSS nastavit background v tom bloku rovnou ten blank obrázek a když se načte obrázek, tak ho překryje, či případně přes JS navěsit událost onError na tagy IMG a když se nenačte obrázek nahradit za cestu k neexistujícímu.
- holantomas
- Člen | 55
Nápad s CSS se mi líbí děkuji za inspiraci. JS se mi nelíbí je to zavádějící, uživatel vypne JS a potom tam bude mít hnusné čtverečky.
- petr.pavel
- Člen | 535
CSS pozadí: Ty čtverečky tam v IE budeš mít taky, protože tvůj obrázek bude nad pozadím. Tudíž i ten [x] bude nad pozadím.
Jako další alternativu nabízím definovat přes .htaccess vlastní 404 dokument – adresu nějaké akce v Nette. Ta potom vrátí/přesměruje na ten incognito-123×456.jpg.
Tím mimo jiné také zajistíš, aby se vracela 404 a prohlížeče/vyhledávače tak pochopili, že obrázek opravdu neexistuje – ne, že byl přesunut (302).
- holantomas
- Člen | 55
petr.pavel napsal(a):
adresu nějaké akce v Nette. Ta potom vrátí/přesměruje na ten incognito-123×456.jpg.Tím mimo jiné také zajistíš, aby se vracela 404 a prohlížeče/vyhledávače tak pochopili, že obrázek opravdu neexistuje – ne, že byl přesunut (302).
Ono je to ale stejné řešení jako uvádí enumag
- holantomas
- Člen | 55
enumag napsal(a):
Moje představa je přibližně následující:
- všechny obrázky budou v jedné složce (nebo několika málo složkách), např. /upload
- pokud obrázek existuje tak se prostě zobrazí, Nette se vůbec nedostane ke slovu (nelze použít v případech kdy je vyžadována autorizace pro zobrazení obrázku)
- pokud obrázek neexistuje, odchytne to přibližně takováhle routa:
$router[] = new Route('uploads/<photo .+>', array( 'presenter' => 'Images', 'action' => 'default' ));
Presenter pak dle parametru photo rozezná jaké rozměry má obrázek mít (to by se dalo řešit už v route a presenter by dostal
$dimensions
či$width
a$height
) a vrátí výchozí obrázek v potřebných rozměrech, případně na něj přesměruje pomocí redirectUrl (sám nevím která možnost je lepší – zda vrátit rovnou nebo přesměrovat).
Jak v tomto případě vyřešit view? Tedy mám udělaný presenter. Z adresy uploads/image.jpg?width=170&height=170 se mi to zroutuje na Noimage:default. Jak teď udělat to aby se mi vykreslil jen samotný nahrazující obrázek ? Aktuálně se mi vykresluje celý layout stránky.
- holantomas
- Člen | 55
enumag napsal(a):
Presenter::sendResponse(new FileResponse)
Můj presenter
<?php
class NoimagePresenter extends BasePresenter {
protected function startup() {
parent::startup();
}
public function actionDefault() {
$this->sendReponse(new \Nette\Application\Responses\FileResponse($this->context->params['wwwDir'] . '/images/incognito.jpg'));
}
}
?>
A laděnka vyhazuje:
`Nette\MemberAccessException
Call to undefined method NoimagePresenter::sendReponse().`
Přižemž se zkoušel i $this->presenter->sendRes… Ale vždy to samé přitom netbeans mi nabízí v obou případech tuto funkci.
- holantomas
- Člen | 55
vvoody napsal(a):
sendReSponse
OMG, tak to se omlouvám :D
Tak všem zúčastněným děkuji. Vše funguje tak jak má.