Zobrazení obsahu z jiného webu v Drupalu 7

Při tvorbě webu s Drupalem se někdy můžete dostat do situace, kdy budete potřebovat získat data z jiného webu. Zpracování RSS výstupu nemusí být vždy dostatečně pružné. Jednou z možností, jak problém vyřešit, je přímý přístup k datům v databázi jiného webu.

Způsobů, jak zpracovávat data z jiných webů, je celá řada. V tomto článku se podíváme na možnosti práce s databází. Postavíme nový modul pro Drupal 7, který bude schopen sáhnout na data jiné instalace Drupalu. Stejně tak je možné navržený postup využít k importu dat z jiného CMS do vaší instalace Drupalu.

Následující ukázka vám předvede, jak vytvořit nový modul, který připraví nový blok s deseti nejnovějšími články z jiného webu. Máte-li k dispozici RSS výstup, můžete tak samozřejmě učinit přes modul Aggregator. Pokud však potřebujete na svém webu zobrazovat data z jiného projektu, který vám běží na serveru, můžete následující postup bez problémů modifikovat.

V praxi podobný postup využívám k vytvoření boxíků pod články na webu cnews.cz - v nich jsou zobrazeny nadpisy a obrázky článků z jiných instalací Drupalu a z jednoho WordPressu. Výsledkem je úplně stejné zobrazení, kterého byste při použití RSS výstupů a Agregátru zřejmě nedosáhli, nebo jen velmi obtížně. Navíc je takto možné získat více článků z jiných webů a náhodně je prostřídat.

Příprava spojení s jinou databází

Abyste mohli z Drupalu 7 navázat spojení s jinou databází, upravte si soubor settings.php ve složce sites/default. Vyhledejte následující část:

 

    $databases['default']['default'] = array(

      'driver' => 'mysql',

      'database' => 'databasename',

      'username' => 'username',

      'password' => 'password',

      'host' => 'localhost',

      'prefix' => '',

    );

Tuto část označte, zkopírovaný text vložte pod ni a následně vloženou část upravte tak, abyste zde uvedli informace o dalším spojení s jinou databází. V případě, že jinou databázi označíte pracovním názvem borrowed, bude vložený řetězec vypadat následovně:

   $databases['borrowed']['default'] = array(                                   

     'driver' => 'mysql',                                                       

     'database' => 'otherdatabasename',                                            

     'username' => 'username',                                            

     'password' => 'password',                                                 

     'host' => 'localhost',                                                    

     'prefix' => '',                                                           

   );  

Soubor settings.php nyní uložte - ujistěte se, že se opravdu uložil. Jelikož je Drupalem nastaven tak, aby do něj nebylo možné zapisovat, zřejmě budete muset před jeho uložením upravit práva pro zápis, například pomocí svého FTP klienta.

Struktura modulu pro Drupal 7

Nyní začněme tvorbu modulu pro Drupal 7. Ve složce sites/all/modules vytvořte novou složku se jménem vašeho modulu. Já v tomto příkladu použiji označení borrowcontent. Ve vytvořené složce připravte dva soubory pojmenované jako:

  • nazev_modulu.info
  • nazev_modulu.module

Já jsem vytvořil soubory pojmenované borrowcontent.info a borrowcontent.module. Aby se Drupal dozvěděl, že nový modul existuje, musíte do souboru info vložit několik informací:

name = BorrowContent

description = Ukázkový modul využívající spojení na jinou databázi

package = Development

core = 7.x

files[] = borrowcontent.module

Můj ukázkový modul má v souboru info následující části:

  • name – označení modulu
  • description – informace o modulu zobrazované v administračním přehledu Drupalu
  • package – název balíčku určuje zařazení modulu do skupiny v přehledu modulů v administraci Drupalu
  • core – určení verze jádra Drupalu, pro kterou je modul určen
  • files[] – tímto způsobem je třeba uvést každý soubor, který tvoří programový kód vašeho modulu

Do souboru *.module vložte na začátek znaky <?php. Tím je základ modulu položen a vy se můžete pustit do sestavení jeho funkcionality.

Vytvoření bloku v modulu pro Drupal 7

Popisovaný modul vytvoří blok s odkazy na deset posledních článků na jiném webu. K vytvoření bloku budou zapotřebí tyto dvě funkce - odkazy vedou na stránku s nápovědou na api.drupal.org:

Pro použití těchto funkcí v našem modulu je třeba je přejmenovat tak, aby místo slova hook měly v názvu označení modulu, tedy to, co máte v názvu souboru před příponou .module.

Funkce hook_block_info() Drupalu sděluje, že naším modulem budou poskytovány nějaké bloky, nebo přinejmenším jeden blok. Tato funkce vrací pole s informacemi o všech blocích poskytovaných daným modulem. Já použiji pouze jeden blok. Pokud byste jich chtěli více, stačí zkopírovat a upravit část s $block[].

function borrowcontent_block_info() {

  $blocks['other_website_latest'] = array(

    'info' => t('Latest articles borrowed from other website'),

    'cache' => DRUPAL_NO_CACHE

  );

  return $blocks;

}

Sekce $block['strojovy_nazev_bloku'] obsahuje pole s alespoň jednou hodnotou, kterou Drupalu sdělujete popisek bloku viditelný v administraci. Já použil ještě zápis sdělující, že daný blok nebude cacheován.

Dále je potřeba vytvořit funkci obhospodařující samotné zobrazení bloku. Drupal ji zavolá pokaždé, když má dojít k vykreslení bloku. Opět zde nahradíte slovo hook v názvu funkce hook_block_view() označením svého modulu:

 

function borrowcontent_block_view($delta = '') {

  $block = array();

  switch ($delta) {

    case 'other_website_latest':

      $block['subject'] = t('Latest articles borrowed from other website');

      $block['content'] = borrowcontent_other_website_latest();

      break;

  }

  return $block;

}

Tato funkce pracuje s označením delta, které určuje, který z bloků poskytovaných vaším modulem se právě zpracovává pro zobrazení. Pomocí operátoru switch a větvení case tak můžete říci, jaký bude nadpis konkrétního bloku a jaká funkce se postará o vytvoření jeho obsahu. V příkladu je jediný blok označený other_website_latest, jak si můžete všimnout výše.

Pokud budete vytvářet více bloků v jednom modulu, pak samozřejmě přidáte do case další případ s označením daného bloku.

Zobrazení dat z jiného webu pomocí Drupalu 7

Nyní tedy máme hotovo následující:

  • připojovací řetězec k další databázi zapsaný v souboru settings.php
  • složku pro nový modul
  • soubory *.info a *.module
  • specifikaci modulu v souboru *.info
  • implementaci funkcí hook_block_info() a hook_block_view()

Poslední část, kterou musíme udělat, je vytvoření funkce, která se postará o naplnění obsahu bloku. Její pojmenování odpovídá mu, co jste uvedli v části u $block[‘content’] v definici zmíněné výše.

function borrowcontent_other_website_latest()

  db_set_active('borrowed');

  $query = "SELECT nid, title FROM {node} WHERE type = 'story' AND status = 1 ORDER BY created DESC LIMIT 0,10";

  $result = db_query($query); 

  $return = '<ul>';

  foreach ($result as $record) {

    $base = 'http:// www.otherwebsiteurl.com /';

    $relative = drupal_get_path_alias('node/'.$record->nid);

    $return .= '<li>'.l($record->title, $base.$relative, array('title'=>$record->title)).'</li>'

  }

  $return .= '</ul>'

  db_set_active('default');

  return $return;

}

Nyní několik slov o tom, co tato funkce provádí. Všimněte si důležitého volání pomocí funkce db_set_active(). Této funkci předáváte parametr s označením pracovního názvu jiné databáze - tak, jak jste jej specifikovali v připojovacích datech v souboru settings.php. Veškeré dotazy na databázi, které od této chvíle Drupal provede, nebudou směřovat do jeho databáze, ale tam, kam jste se voláním db_set_active() připojili.

Stejnou funkci, ovšem ve tvaru db_set_active('default') musíte tedy zavolat ihned poté, co jste s prací na cizí databázi hotovi. Jinak by v Drupalu došlo k chybě, protože by neměl spojení se svou vlastní databází.

Následuje vytvoření řetězce s SQL dotazem do databáze. Název tabulky je uzavřen ve složených závorkách - Drupal jej automaticky převede na správný tvar. Jinými slovy, název tabulky uvádíte bez prefixu a je-li v připojovacím řetězci v settings.php uveden nějaký prefix názvů tabulek, Drupal jej do dotazu automaticky doplní.

V uvedeném dotazu získávám nid označení uzlů z jiné instalace Drupalu a také jejich názvy. Dotaz je omezen jen na uzly typu story a uzly ve stavu vydáno.

Voláním db_query() zpracujete výsledky databázového dotazu. Ukázkové řešení zpracovává data jako seznam HTML značek LI uzavřených mezi značkami UL.

Ve smyčce foreach modul projde jednotlivé řádky získané dotazem do databáze a vytvoří odkazy na každý ze získaných článků. Protože funkce l() nepracuje s absolutními cestami, je kód o trošičku složitější, než by možná bylo záhodno.

Do proměnné $base je vložen základ adresy webu, z jehož databáze jsou získávána data. Jelikož jsme dotazem do databáze získali identifikátory uzlů NID, můžeme použít volání funkce drupal_get_path_alias() a získat relativní cestu k uzlu. Funkcí l() se pak základní adresa a relativní cesta spojí a zároveň se vytvoří HTML řetezec pro odkaz. Parametry funkce l() jsou řetezec, na který bude uživatel klikat, cesta odkazu a pole s atributy odkazu - zde s doplněním atributu title pro HTML značku A.

Ještě jednou připomínám, že musí dojít k zavolání db_set_active('default'), aby došlo k navázní spojení s domovskou databází. Funkce na konci vrátí poskládaný řetězec se seznamem odkazů a ten se pak pomocí výše definovaného hook_block_view() zobrazí v těle bloku.

Vylepšení s pomocí DBTNG

Drupal 7 přišel s vylepšenými funkce pro práci s databází. Setkáte se s nimi pod označením DBTNG, což znamená Database Layer: The Next Generation. Pokud raději tvoříte přímo SQL řetezce, klidně použijte kód uvedený výše. Já vám nyní naznačím přetvoření uvedené funkce tak, aby pracovala právě s DBTNG.

function borrowcontent_other_website_latest()

  db_set_active('borrowed'); 

  $select = db_select('node', 'n')

  ->fields('n', array('nid','title'))

  ->condition('n.type','story')

  ->condition('n.status',1)

  ->orderBy('n.created','DESC')

  ->range(0,10); 

$nodes = $select->execute()->fetchAll();

  if (!empty($nodes)) {

     $return = '<ul>';

    foreach ($nodes as $node) {

       $base = 'http:// www.otherwebsiteurl.com /';

       $relative = drupal_get_path_alias('node/'.$node->nid);    

       $return .= '<li>'.l($node->title, $base.$relative, array('title'=>$node->title)).'</li>';

}

    $return .= '</ul>';

  } 

  db_set_active('default');

  return $return;

}

Struktura takto upravené funkce je velmi podobná předchozí verzi. Opět je zde dvojice volání db_set_active(). Řetězec SQL zmizel a nahradil jej tento zápis:

  $select = db_select('node', 'n')

  ->fields('n', array('nid','title'))

  ->condition('n.type','story')

  ->condition('n.status',1)

  ->orderBy('n.created','DESC')

  ->range(0,10); 

Přiznám se, že když jsem poprvé viděl zápis kompatibilní s DBTNG, nepřišel mi srozumitelný. Jakmile jsem však pochopil, k čemu slouží, nemám s ním žádný problém. Jeho výhodou je, že na pozadí připraví SQL dotaz komptibilní s různými databázemi, které Drupal podporuje, takže se drobnými rozdíly v zápisu SQL nemusíte vůbec zabývat.

Funkcí db_select() vyíráte tabulku, jejíž daa chcete zpracovat a nějak si ji označíte. V tomto případě jsem vybral tabulku node a označil ji písmenem n. Následuje výběr políček z této tabulky - potřebuji dvě - nid a title.

Následují dvě podmínky, tvořící v první alternativě této funkce část SQL dotazu v klauzuli WHERE. Zápisem orderBy je nasaveno řazení a zápisem range je omezen počet získaných dat - tedy podobně, jako v SQL dotazu klauzulí LIMIT.

Voláním $select->execute()->fetchAll() obdržíte objekty s řádky získanými z databáze. Zápis je možné modifkovat do podoby $select->execute()->fetchAll(PDO::FETCH_ASSOC), kdy místo objektů získáte pole.

Kompletní modul ke stažení

Věřím, že tato jednoduchá ukázka kombinující hned několik úkolů (tvorba bloku, práce s databází a přepínání na jinou databázi) vám pomůže ve vašich projektech. Kompletní modul ke stažení najdete v anglickém originálu tohoto článku na How to display content from other website using your own simple Drupal 7 module.

Tagy

Buďme ve spojení, přihlaste se k newsletteru

Odesláním formuláře souhlasíte s podmínkami zpracováním osobních údajů. 
Více informací v Ochrana osobních údajů.

Autor článku: Jan Polzer

Tvůrce webů z Brna se specializací na Drupal, WordPress a Symfony. Acquia Certified Developer & Site Builder. Autor několika knih o Drupalu.
Marketing Director v Lesensky.cz. Ve volných chvílích podnikám výlety na souši i po vodě. Více se dozvíte na polzer.cz a mém LinkedIn profilu.

Komentáře k článku

návštěvník

Ahoj

to mas na maxiorlu nakej ban? jak to ze po prepoctu pranku mas jen 2? me na skoro na vsech webech narostl prank na 3 a to i na jedno strankovy weby na ktery neodkazuji ani na nich neni zadnej text jen trapna uvodni stranka,ktera ceka az si na projekty najdu cas

tenhle web ma solidni navstevnost a castou aktualizaci a i zpetny odkaz, tak v cem je problem? zeby google nemel rad Drupal?

Profile picture for user Jan Polzer

To nesouvisí s tímto článkem... O PageRank se nestarám, zajímá mě skutečná návštěvnost, spokojenost čtenářů a případně zisk z reklamy, nikoli virtuální hodnocení, které se v tomto už dávno neodráží... No a proč má Maxiorel nízký PageRank? Možná proto, že jsem tu kdysi měl systém pro prodej a výměnu zpětných odkazů, nevím. Ale to je už dávno.
Jak sám píšete, jestliže mají neudržované weby s trapnou úvodní stránkou větší PageRank, pak je toto hodnocení ve vztahu k reálnému posouzení kvality webu, k ničemu :-) Google se na mne určitě nezlobí, ve vyhledávačích je Maxiorel umístěn docela dobře.

Přidat komentář

Odesláním komentáře souhlasíte s podmínkami Ochrany osobních údajů

reklama
Moje kniha o CMS Drupal

 

Kniha 333 tipů a triků pro Drupal 9


Více na KnihyPolzer.cz

Sledujte Maxiorla na Facebooku

Maxiorel na Facebooku

Poslední komentáře
Hosting pro Drupal a WordPress

Hledáte český webhosting vhodný nejenom pro redakční systém Drupal? Tak vyzkoušejte Webhosting C4 za 1200 Kč na rok s doménou v ceně, 20 GB prostoru a automatické navyšováním o 2 GB každý rok. Podrobnosti zde.

@maxiorel na Twitteru

Maxiorel na Twitteru