imagefield + imagecache - pseudo filter

aboros képe

A konferencia utolsó részében a redesing beszélgetésen merült fel kérdésként, hogy mit ad a haladóknak a drupal.hu és hogyan lehet kinyerni belőle ezt a hasznos infót. Konferencia után, sörözés közben még többet beszélgettünk erről, így a gondolattérképbe már be is építettem egy "Trükktarisznya" fantázianevű fórumot, amiből aztán a legjobbakat egy "Tippek-trükkök" könyvbe lehetne rendezni, felhasználási terület, nehézségi szintek vagy mittudomén micsoda alapján.

Hogy ne csak a levegőbe lövöldözzek, én most beküldök egy ilyen tippet, magam készítettem és nagyon elégedett vagyok vele ;) de minden kritikát, jótanácsot szívesen fogadok.
(ez lenne ugye ennek a rovatnak az értelme, itt nem segítséget kér a témaindító, hanem segítséget nyújt még fel sem tett kérdéshez:)

A snippet -em (kódmorzsa?) a template_preprocess_node() használatával, imagefield -el node -hoz csatolt képeket helyez a tartalomba egy előre meghatározott minta előfordulásainak helyére úgy, hogy azokat a mintában megadott imagecache sablonon is átzavarja és extra classt is ad neki, ha kell.

Kezdjük is el!

Töltsük le és telepítsük a Drupal 6.x verzióját, egészítsük ki az alábbi modulokkal:
- cck
- imagefield (ehhez kelleni fog a filefield is)
- imagecache (ehhez kelleni fog imageapi)

Valamelyik tartalom típusunkhoz adjunk az imagefield segítségével egy image típusú mezőt. Nem feltéltenül szükséges, de ha gondoljuk a 'Mezők megjelenítése' fülön állítsuk ezt a mezőt teaser es full page nézetben is rejtettre. (a példában ennek a mezőnek a neve: field_image)

Az imagecache modullal hozzunk létre nekünk tetsző mennyiségű sablont és kedvünk szerint állítsuk be azokat. Akárhány ilyen sablont létrehozhatunk, próbáljunk azonban beszédes neveket adni ezekenek, hiszen később ezekre kell majd hivatkoznunk. (a példában én 3 ilyen sablont hoztam létre, ezek nevei: small, medium, large)

Nyissuk meg a sminkünk template.php fileját, ha nincs ilyen, hozzuk létre azt! Győződjünk meg róla, hogy ebben a fileban még nincs megvalósítva a SMINKNEVE_preprocess_node() függvény. (ha mégis szerepelne ilyen, akkor sincs baj, a kódunkat a függvény végére illeszthetük)

template.php:

function SMINKNEVE_preprocess_node(&$vars) {
 $node = $vars['node'];
 
 /* pseudo-filter */
  if (isset($node->field_image[0])) {
    preg_match_all("#\[img:([0-9]+):([a-z]+):([a-z]+)\]#", $vars['content'], $matches, PREG_SET_ORDER);
    foreach ($matches as $match){
    $image = $node->field_image[$match[1]-1];
    $original = file_create_url($image['filepath']);
    $preset = $match[2];
    $class = $match[3];
    #$alt = '';
    #$title = '';
    $options = array(
        'html' => TRUE,
        'attributes' => array(
          'rel' => 'lightbox['.$vars['nid'].']',
          'class' => $class
        )
    );
 
    $thumb = theme('imagecache', $preset, $image['filepath'], $alt, $title, $attributes);
    $img = l($thumb, $original, $options);
 
    $vars['content'] = str_replace($match[0], $img, $vars['content']);
 
    }
  }	/* end: pseudo-filter */
}

Ezután már csak egy dolgunk van, css -ben hozzunk létre néhány szabályt, amiket majd használni szeretnénk. Mivel a filter az l() függvényben magához az 'a' teghez illeszti majd a classokat, ezek praktikusan például ilyenek legyenek:

a.left {
float: left;
margin: .3em 1em 1em 0;
}
a.right {
float: right;
margin: .3em 0 1em 1em;
}
stb..

Mentsünk el mindent, töröljük a sminkleíró tárat az ismert módszerek valamelyikével és igazából készen is vagyunk.

Najó, de hogyan használhatjuk? :)

Küldjünk be egy új példányt abból a tartalom típusból, amelyik rendelkezik az elején létrehozott field_image mezővel és töltsünk is legalább egy képet ebbe a mezőbe. Filterünknek hála (tudom, nem filter, de majdnem) a tartalom törzs részében elhelyezhetjük ebbe a képmezőbe töltött képeinket, akár ugyan azt többször is, például így:

[img:1:small:left] <- ennek helyére megtekintéskor a field_image mezőben szereplő első kép, "small" nevű imagecache sablonnal kezelt változata kerül, egy "left" osztállyal ellátva.

[img:5:large:right] <- ennek helyére megtekintéskor a field_image mezőben szereplő első kép, "large" nevű imagecache sablonnal kezelt változata kerül, egy "right" osztállyal ellátva.

Remélem nincsenek benne túl nagy hülyeségek és valaki talán hasznát tudja venni, ha más nem ötleteket adhat, mire és miért jók az előfeldolgozók.

Melyik modulhoz, modulokhoz kapcsolódik a téma?: 
Drupal verzió: 
Fórum: 
eMeLA képe

Ez a SMINKNEVE_preprocess_node() pontosan mikor hívódik meg ? A node.tpl.php előtt ?

0
0

...mit tudok: http://web.termuves.hu

nevergone képe

Igen, az állítja össze a node.tpl.php számára a változók tartalmát.

0
0
nevergone képe

Picit arról a template.php -s varázslásról mesélsz még? Mármint hogy dolgokat miért úgy oldottál meg a függvényben, és mi a szerepük. :)

0
0
aboros képe

pontosan melyik mozdulatot kéne elmagyarázni? (neked??)
bevallom a legnehezebb az egészben a reg.exp minta megírása volt. soha életemben nem használtam még ilyet, láttam ugyan mások kódjában a fura kriksz-kraksz-sorozatokat, de fogalmam nem volt mire és hogyan és egyátalán.

elég nehéz volt megérteni, elsőre nem is igazán ment, aztán drupal.hu irc csatornán boobaa adta a jelenleg is használt mintát. (ezen keresztül már elég jól megértettem azt hiszem, azóta gyakran mahinálok ilyen-olyan felülírásoknál preg_replace -el, tetszik;)

szóval pontosan melyik sort mondjam el részletesebben? szívesen elmondom, ha megmondod, mi nem világos!

0
0

-
clear: both;

nevergone képe

Nem nekem, hanem az utókornak. Én kipróbáltam, kikisérleteztem, amit írtál, és működik. De talán másnak nem ártana egy pár sor megjegyzés, pl. a mintához. :)

0
0
aboros képe

szerintem magában a felvetésben még ennyi magyarázat is sok. :) ha érdemes rá, irány a "Trükkök" könyv(lap?) és akkor ott már magyarázat, akár soronként. legjobb, ha bárki szerkesztheti az ilyen könyvlapokat, hozzátehet a kódhoz vagy akár a magyarázathoz.

0
0

-
clear: both;

zserno képe

Ügyes trükk és jó kezdeményezés, gratulálok. Sok ötlet felmerült bennem hirtelen:

  • Ha a cikk segítségre szorulóknak szól, akkor mindenképpen valami beszédesebb címre kell keresztelni (mint pl. „Hogyan illeszthetünk be korlátlanul képeket egy tartalomba (imagefield+imagecache+lightbox használatával)?” vagy „Képbeszúrás szabadon”,...).
  • Ha összeszednénk az előnyeit szépen (hogy miért más ez, mint bármelyik eddigi megoldás), akkor egy modul formájában közzé is tehetnénk, így még egyszerűbbé téve a segítségre szorulók dolgát (plusz sminkfüggetlen lehetne).
  • Annyi ilyen jó ötlet született már, amiből szép modulok készülhetnének, ezért arra gondoltam, hogy lehetne az új drupal.hu-nak egy „ötletláda” része, ahol programozáshoz nem értők (de jó ötlettel/igénnyel rendelkezők) olyan ötleteket dobhatnának be, amikből hasznos modulok készülhetnének. Sokan úgyis azon panaszkodnak, hogy nincs olyan modul, amit még nem írtak meg :)
0
0
aboros képe

igen, beszédesebb cím kell, ezt a témát egy példának szántam, hogy ilyesmi kódmorzsákat gondolok bele egy trükktarisznya könyvbe/szekcióba kinek mi tetszik. egy adott fórumtémába érkezhetnének ezek, akármilyen címmel, az arra érdemeseket (kap elég "+1" -et a közösségtől vagy annyira, de annyira bomba trükk, hogy még azt se várjuk meg) pedig amikor könyvbe helyezzük, úgyis adunk a könyvlapnak beszédes címet.

először egy filter típusú modulba próbáltam ezt belegyúrni, de azzal az volt a gondom, hogy minden filter-képes szövegbeviteli mezőre értelmeződött, egy darabig agyalgattam, hogyan kéne korlátozni csak törzs mezőre, de aztán inkább megírtam egy előfeldolgozóba pikk-pakk.

egyébként valami ilyesmit készül megvalósítani az inline modul is, csak nem filefield (imagefield, stb) mezőkkel, hanem upload modullal csatolt fileokkal. érdekes kezdeményezés, bevallom némileg onnan jött az ötlet. ;) http://drupal.org/project/inline

0
0

-
clear: both;

Paal képe

Szia!

Sajnos már nem emlékszek hogy hol, de olvastam/néztem (lehet, h videó volt) korábban egy leírást, ahol pont ilyen, képek tartalomba való beszúrása volt megoldva azt hiszem a Rep[lacement]Tags modul segítségével.

Végül is hasonló eredményt lehetett elérni vele, mint Ádám megoldásával.

Nem tudja/látta véletlenül valaki azt a cikket? Azt is berakhatnánk a kézikönyvbe, mint megoldás.

0
0

--
Palócz Paal Pál, a drupal.hu admin csoportjának tagja
Ajánlott olvasmány: Eric Steven Raymond - Hogyan kérdezzünk okosan

york képe

Szia

[img:5:large:right] <- ennek helyére megtekintéskor a field_image mezőben szereplő első kép, "large" nevű imagecache sablonnal kezelt változata kerül, egy "right" osztállyal ellátva.
^ nem az 5. kep?

0
0
aboros képe

természetesen igen.
csak kopiztam az előtte levő példát és elfelejtettem átírni azt. bocs vagyok!

0
0

-
clear: both;

teecee képe

... :)

Pont ilyet keresek, de úgy, hogy nem egy node-hoz való feltöltött képet, hanem másik node-ban lévő mezőt helyettesít be. (Egy kép több tartalomnál is lehet a jelenlegi elgondolás szerint és jó lenne, ha nem kellene mindig feltölteni.)
Persze lehet, hogy logikailag nem szerencsés, amit gondoltam, lévén egy kép (illusztráció) egy node-hoz tartozik, akkor jobb lenne, ha 'amellett' lenne...
Még gondolkodom rajta.

Köszi!

0
0

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TeeCee, the One and Only

aboros képe

talán.

az imce egy fileböngésző-szerűség leginkább, minden felhasználó akinek van joga használni azt, tölthet fel képeket, ilyen-olyan fileokat, ha jól emlékszem még mappákba is rendezheti azokat.
soha nem próbáltam, de nem tartom lehetetlennek, hogy az ezzel feltöltött fileokat egy hasonló pseudo-filterrel beágyazhassák a felhasználók.

a témaindító megoldás tényleg inkább olyankor jó, mikor egy kép csak egy nodehoz tartozik, ha nem így van, akkor használhatósági gondok merülnek fel. például lehetne azt, hogy node reference mezővel lehet egy nodera hivatkozni és akkor annak a képeit is lehet beágyazni, de ezzel (egyebek mellett például) az lesz a baj, hogy a beküldő űrlapon csak a node reference mezőt fogod látni, a hivatkozott nodehoz csatolt képeket már nem. és például ha megváltoztatod a képsorrendet vagy eltávolítod a képet (amitől máris változik a sorrend is), akkor máris borul minden olyan tartalmad, ami ennek a nodenak a képmezőjét is használja. nem szerencsés.

olyan pseudo-filternek semmi akadályát nem látom, amivel a files mappán belül található útvonalak valamelyikében lévő képekre lehet hivatkozni. ilyen irányú törekvés például az inline modul, érdemes megnézni.

0
0

-
clear: both;

teecee képe

... a gyors választ!

Nekem ez azért jó, mert a szöveges tartalmak mellé rakott illusztrációkat ImageCache-el átméretezem, mintát rakok rá, és így az egész oldalon egységes kinézetű képecskék lesznek, míg a símán csak fájlokat belinkelve gondban lennék, ha változik pl. az imagecache preset neve...

A Drupalhoz rendszerszinten sajnos nem értek, nemrég kezdtem magam beleásni, ugyanakkor egyből küldenék egy kis kiegészítést:
itt egy kis módosítás, hogy több tartalomtípusra és tartalomtípusonként egy mezőre is működjön a ugyanez a kód. Kommenteztem a módosításokat. hátha valaki ezt is hasznosnak tartja...

function SMINKNEVE_preprocess_node(&$vars) {
	$node = $vars['node'];
	// Asszociatív tömbben megadjuk a tartalomtípust és a mezőnevet
	$fields = array(
		'page'            => 'field_illustration',
		'masik_node_type' => 'masik_mezonev'
		);
	// Ha elírtunk valamit, vagy csak szimplán nincs ilyen nevű mező a node-ban, akkor nem foglalkozunk az értelmezéssel
	// (nem mellesleg a php FATAL ERROR-t dob nemlétező property használatakor ;-)
	if ( !property_exists( $node, $fields[$node->type]) ) {
		return false;
	}
	// Itt egy olvashatóbb változónév a képmezőkre:
	$picFields = $node->{$fields[$node->type]};
	/* pseudo-filter */
	// Ha van feltöltve kép egyáltalán, akkor nézzük csak meg, hogy van-e értelme az átalakításnak
	if ( isset($picFields[0]) ) {
		preg_match_all("#\[img:([0-9]+):([a-z]+):([a-z]+)\]#", $vars['content'], $matches, PREG_SET_ORDER);
		foreach ($matches as $match){
			// Itt szintén a képmezős változót haszáljuk...
			$image = $picFields[$match[1]-1];
			$original = file_create_url($image['filepath']);
			$preset = $match[2];
			$class = $match[3];
			#$alt = '';
			#$title = '';
			$options = array(
				'html' => TRUE,
				'attributes' => array(
					'rel' => 'lightbox['.$vars['nid'].']',
					'class' => $class
				)
			);
 
			$thumb = theme('imagecache', $preset, $image['filepath'], $alt, $title, $attributes);
			$img = l($thumb, $original, $options);
			$vars['content'] = str_replace($match[0], $img, $vars['content']);
		}
	}    /* end: pseudo-filter */
}

// update 2009/01/09: egy elírás volt benne, azt javítottam

0
0

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TeeCee, the One and Only

Boobaa képe

...aztán nem fejeztem be, mert nálam okosabb, ügyesebb, tapasztaltabb, stb. arc már megcsinálta. Igaz, nem ugyanezt (nem filter alapon, ergo alkönyvtárbeli dev site-ot nem fogok tudni vele webrootba élesíteni), viszont felhasználóbarátabban (legalábbis szerintem). Lightbox2 megy rajta out-of-the-box, tartalomszerkesztő űrlap imagefield-feltöltő részéből kiválasztható a használandó imagecache preset, a mellette levő gombbal meg berakja a törzsbe. Egyszerű, működik - legalábbis az alap szerkesztővel (FCK és társaival még nem próbáltam).

Egyúttal felhívnám a figyelmet arra az apróságra, hogy a tartalom kellő változtatása után (gondolok itt elsősorban a lista eleje felé található képek törlésére) a képekre mutató "hivatkozások" hibásak lesznek, hiszen megváltozott a számuk. Erre az inline.module esetén azt találták ki, hogy a hook_nodeapi() prepare és presave szakaszában a számmal történő hivatkozást átalakítják fájlnévvel történő hivatkozásra, ami így nyilván ugyanazon képre fog hivatkozni akkor is, ha valamely előtte levő képet törölnek (netán a listát átrendezik).

Igazából már csak az kéne, hogy a filefield_insert az inline-hoz hasonlóan filterként működjön, hogy lehessen alkönyvtárban tartani a dev site-ot... Issue beküldve - reméljük a legjobbakat.

0
0
aboros képe

és a tegnapi security előadás után rögtön láttam, hogy itt bizony lyuk van.
remélem ez javítja. arra gondolok, hogy amit "preset" és "class" -ként kérek be, azon semmilyen ellenőrzést nem végeztem. de ez baj, remélem ha egy check_plain -en átkergetem őket rendben leszek. (persze okosabb lenne ellenőrizni, hogy létezik e mondjuk az imagecache preset, meg eleve figyelni kéne, hogy van e imagecache modul, úgyhogy akkor már azt is adjuk hozzá)

íme:

function SMINKNEVE_preprocess_node(&$vars) {
$node = $vars['node'];
 
/* begin: pseudo-filter */
  /* ha van erteke a mezonek, es van imagecache modul es van lightbox2 modul is, csak akkor akciozunk, mert kulonben error */
  if (isset($node->field_image[0]) && (module_exists('imagecache') && module_exists('lightbox2'))) {
    preg_match_all("#\[img:([0-9]+):([a-z]+):([a-z]+)\]#", $vars['content'], $matches, PREG_SET_ORDER);
    foreach ($matches as $match){
    $image = $node->field_image[$match[1]-1];
    $original = file_create_url($image['filepath']);
    /* figyelj, barmit beirhatott, ha gonosz */
    $preset = check_plain($match[2]);
    $class = check_plain($match[3]);
    /* itt meg kiegeszitheted amivel gondolod, hogy az legyen az alt meg a title. lehet egy mezo de az imagefieldben is van ugye description meg title */
    $alt = '';
    $title = '';
    $options = array(
        'html' => TRUE,
        'attributes' => array(
          'rel' => 'lightbox['.$vars['nid'].']',
          'class' => $class
        )
    );
 
    $thumb = theme('imagecache', $preset, $image['filepath'], $alt, $title, $attributes);
    $img = l($thumb, $original, $options);
 
    $vars['content'] = str_replace($match[0], $img, $vars['content']);
 
    }
  }    /* end: pseudo-filter */
}

remélem így már okés. ha esetleg még használja valaki, ajánlott "frissíteni az új biztonsági kiadásra" :)

0
0

-
clear: both;

Désiré képe

Szerintem itt nincs szükség a check_plain -re, mivel előtte a regexp -el a '(a-z)+' mintát használtad, az pedig ugye csak az angol abc kisbetűit engedi át, tehát ha valaki gonosz, akkor a kódja már el sem jut a check_plain-ig.
Jól gondolom?

Ezen kívűl ami engem érdekelne, az az, hogy van-e különösebb oka, hogy ezt a _preprocess_node-val oldod meg, és miért nem mondjuk a hook_nodeapi hívásával? ($op = 'alter')
Köszi.

0
0

- - -
Juhász Márton

http://juhaszmarton.hu

aboros képe

sajna nem vagyok regexp magus tanonc. se. ;) ugyhogy azt boobaa bacsi adta nekem oda ircen. de logikusnak tunik az ervelesed. preprocess meg azert, mert akkor az nagy csoda volt nekem, orrverzesig preprocesszaltam nap, mint nap es a nodeapi szamomra meg a kanyarban sem volt.

azota persze majdnem egy ev is eltelt, nagyot fordult a vilag velem meg amugy is, pl kijott a drupal 7 :) meg egesz jopofa modulok vannak amik ilyesmiket csinalnak pl az insert. bar az sajnos belevagja a html kodot a szovegmezobe. ennek elonye hogy rogton latod a wysiwyg editorba, az a hatranya, hogy utolag nem tudsz valtoztatni ugye. ha teszem azt valtoztatni kell az oda kerulo html szerkezetet akkor azt nem tudod ugy megtenni, hogy atirod az insert templatejet, mert az utolag mar nem lesz ervenyes, a html mar a body mezobe van.

valami filter feleseg kene, amit a modulunk szerkeszteskor js segitsegevel forgat htmlre, de a mezobe nem a htmlt menti, hanem egy fentihez hasonlo markupot. de amugy ez se az igazi. :) az lenne jo ha feluleten hozhatnal letre "insert sablonokat" es a markupba csak a valasztott sablon idje kerulne. utolag is varialhatnad a sablont ahogy akarod. szerkeszto feluleten meg egy szovegmezobe irod a htmlt szepen, tokenek segitenek. vagy ilyesmi. nemtom mostanába máson gondolkodok :)

0
0

-
clear: both;