Tworzenie komponentu w Mambo CMS

Metryka

Tytuł: Tworzenie komponentu w Mambo CMS (ver. 4.5 i 4.5.1)
Autor oryginału: Joseph Lawrence LeBlanc
WWW Autora: http://www.jlleblanc.com
Kontakt: Ten adres email jest ukrywany przed spamerami, włącz obsługę JavaScript w przeglądarce, by go zobaczyć
Autor tłumaczenia i komentarzy: Izydor
Kontakt: Ten adres email jest ukrywany przed spamerami, włącz obsługę JavaScript w przeglądarce, by go zobaczyć

Wstęp

Kurs jest tłumaczeniem angielskiego podręcznika Mambo Component Tutorial - Daily Message Component - autorstwa Joseph Leblanca ( Ten adres email jest ukrywany przed spamerami, włącz obsługę JavaScript w przeglądarce, by go zobaczyć ). Autor udzielił mi ’błogosławieństwa’ i pozwolił na zmiany i własne komentarze. Oryginalny kurs pozwolił mi szybko rozpocząć pisanie własnego komponentu do Mambo. Uznałem, że jest to najlepszy kurs osiągalny w sieci. Autor na swoich stronach (http://www.jlleblanc.com/) cały czas poprawia swój kurs, dodaje nowe elementy. Ja oparłem swoje tłumaczenie na wersji PDF.
Postaram się wiernie oddać oryginał, a tam gdzie dodam coś od siebie, zaznaczę to wyraźnie pochyloną czcionką.

Kurs opisuje budowę w pełni funkcjonującego komponentu wraz z częścią administracyjną. Po zapoznaniu się z kursem powinieneś zrozumieć koncepcję działania Mambo, poznać podstawowe klasy i funkcje. Jest to podstawowa wiedza pozwalająca na rozpoczęcie prac nad własnym komponentem. Sam komponent - w pełni działający - można zassać z http://www.jlleblanc.com. Komponent pracuje w MAMBO 4.5 oraz 4.5.1 .

Każdy rozumie funkcjonalność komponentów Mambo w różny sposób. Programiści znający PHP pewnie zechcą rozpocząć od zrozumienia widocznych części komponentu, plik dailymessage.php (generuje to, co widzą odwiedzający nasze strony) oraz plik admin.dailymessage.php (generuje to, co widać po stronie administratora). Inni mogą zechcieć zacząć od zrozumienia pliku XML, który dokładnie opisuje składowe elementy komponentu.

Opisywany tutaj komponent składa się z:

  • dailymessage.php - generuje to, co widzą odwiedzający nasze strony
  • admin.dailymessage.php - generuje to, co widać po stronie administratora
  • admin.dailymessage.html.php - plik pomocniczy do powyższego, generujący kod html
  • dailymessage.class.php - definicje klas komponentu pomocne przy korzystaniu z bazy danych
  • toolbar.dailymessage.php - generuje pasek narzędzi po stronie administratora
  • toolbar.dailymessage.html.php - plik pomocniczy do powyższego, generujący kod html
  • install.dailymessage.php / uninstall.dailymessage.php - pliki wspomagające proces instalacji i deinstalacji komponentu
  • dailymessage.xml - plik instalacyjny, opis komponentu

/components/com_nazwakomponentu ( w naszym przypadku /components/com_dailymessage). Część administratora wraz z plikami instalacyjnymi wędruje do /administrator/components/com_nazwakomponentu (w naszym przypadku /administrator/components/com_dailymessage). Dodatkowe podkatalogi, potrzebne np. do przechowywania grafiki, będą podkatalogami powyższych lokalizacji odpowiednio dla części administratorskiej oraz frontendu np. /componenst/com_dailymessage/images/ - podkatalog z obrazkami niezbędnymi do wyświetlenia części frontowej.

Ten plik generuje to, co widzą odwiedzający nasz portal, kiedy oglądają komponent Daily Message (Wiadomość Dnia). Kod programu jest nieskomplikowany i w zupełności wystarcza w różnych możliwych zastosowaniach Mambo. Jest to jedyny plik, który znajdzie się w katalogu /componenst/com_dailymessage/. Zapoznajmy się krok po kroku z jego zawartością.

<?php 
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

Ta linia sprawdza, czy nasz plik jest wywoływany poprzez Mambo. Powoduje, że bezpośrednie wywołanie pliku nie jest możliwe. Czyli - jeśli ktoś by próbował otworzyć stronę http://www.twojastrona.com/componenst/com_dailymessage/dailymessage.php otrzymałby komunikat Direct Access to this location is not allowed [Bezpośredni dostęp do pliku zabroniony]. Swoją drogą możesz śmiało zmienić komunikat w powyższej linii na coś bardziej swojsko brzmiącego jak - 'Jak śmiesz próbować tych brudnych sztuczek'.

global $database;

Instrukcja ’global’ powoduje, że zadeklarowany wcześniej w Mambo obiekt bazy danych jest dostępny do użytku w naszym programie.

 // get configuration information
    $database->setQuery("SELECT * FROM #__joe_dailymessage_conf LIMIT 1");
    $rows = $database->loadObjectList();
    $row = $rows[0];

Pobieranie ustawień komponentu poprzez wykonanie zapytania do bazy danych. Wykonanie zapytania do bazy MYSQL jest wykonywane w Mambo w dwóch krokach. Pierwszy to zdefiniowanie treści zapytania poprzez funkcje setQuery. Drugi krok to wykonanie i odczytanie wyników zapytania poprzez użycie funkcji loadObjectList(). Zmienna $row - $row[0] przechowuje informacje z pierwszego obiektu otrzymanego w wyniku zapytania. Jako, że chcemy tutaj uzyskać informacje o ustawieniach komponentu powinniśmy otrzymać tylko jeden obiekt w wyniku tego zapytania. Proszę sobie wyobrazić taki obiekt ($row) jako jeden wiersz z bazy danych otrzymany w wyniku zapytania. $rows przechowuje wszystkie wiersze zwrócone w wyniku zapytania.

Warto zauważyć, że znaki '#_' zostają automatycznie zamienione na prefiks tabel bazy danych, jaki ustaliliśmy podczas instalacji lub ustawiliśmy w konfiguracji Mambo. Standardowo takim prefiksem jest mos (czyli u nas tabela nazywa się mos_joe_dailymessage_conf). Ta funkcjonalność jest przydatna, gdy baza danych musi być współdzielona poprzez różne aplikacje lub na tanich hostach, które udostępniają tylko jedna bazę danych.

     $bold = $row->bold;
     $italic = $row->italic;
     $underline = $row->underline;
     $showdate = $row->showdate;

Po tym, jak uzyskaliśmy informacje z bazy danych, możemy stworzyć zmienne, których użyjemy za chwile.

Uwaga!Powyższe zmienne przechowują informacje o pogrubieniu ($bold), pochyleniu ($italic), podkreśleniu ($underline), znaczniku daty ($showdate).

    if($bold == 1)  {
        $starttags .= "<strong>";
        $endtags = "</strong>" . $endtags;
     }
    if($italic == 1)  {
        $starttags .= "<i>";
        $endtags = "</i>" . $endtags;
     }
    if($underline == 1)  {
        $starttags .= "<u>";
        $endtags = "</u>" . $endtags;
     }

Powyższe instrukcje budują znaczniki HTML w zależności od naszych ustawień. Znaczniki te zostaną użyte poniżej podczas wyświetlania Wiadomości Dnia.

Uwaga!Tak więc jeśli ustawiliśmy w konfiguracji komponentu, ze wiadomość ma być pogrubiona ($bold) dodajemy znaczniki HTML: <b> i </b> itd.

//get data and output accordingly
     $database->setQuery("SELECT * FROM #__joe_dailymessage WHERE published = '1'");
     $rows = $database->loadObjectList();

Używając tego samego obiektu bazy danych oraz metody zapytania opisanej powyżej uzyskujemy wszystkie wiadomości dnia, jakie powinniśmy pokazać odwiedzającemu nasz portal. Obiekt $rows będzie teraz zawierał wszystkie wiadomości.

     ?>
          <table>
     <?php

Zaczynamy generować kod HTML. Znacznik ?> pozwala nam wyjść z trybu PHP, aby móc przesłać do przeglądarki kod HTML dopóki nie napotka znacznika <? (ponowne wejście do trybu PHP). Efekt jest taki sam jak przy użyciu funkcji echo()w PHP.

Uwaga!W powyższej linii zaczynamy tworzyć tabele z Wiadomościami Dnia.

     foreach($rows as $row)  {
          if($showdate == 1)
               echo "<tr><td>" . mosFormatDate($row->date) . "</td>";
          else
               echo "<tr>";
                echo "<td>" . $starttags . $row->message . $endtags . "</td></tr>";
          }

Pętla foreach przegląda obiekt $rows i zapisuje każdą przechowanej tam wiadomości dnia w zmiennej $row. Następnie tworzymy kod HTML korzystając z wcześniej stworzonych znaczników.

     ?>
          </table>

Zamykamy tryb PHP oraz tabele HTML z Wiadomościami Dnia.

Ten plik zawiera logikę administracyjnej strony komponentu, czyli reakcję na Twoje klikanie w panelu administracyjnym. Plik zawiera tylko kod PHP, natomiast aktualny kod HTML generowany na stronach jest generowany poprzez klasę HTML_joeDailyMessage zdefiniowaną w pliku admin.dailymessage.html.php.

Uwaga!Krótko mówiąc tutaj definiujemy, co zrobić, kiedy klikniemy na administratorskim pasku narzędzi na ikonie ’Zapisz’, ’Nowy’ itp.

<?php 
     defined('_VALID_MOS') or die('Direct Access to this location is not allowed.');
 
// ensure user has access to this function
     if (!($acl->acl_check( 'administration', 'edit', 'users', 
          $my->usertype, 'components', 'all' )
          | $acl->acl_check( 'administration', 'edit', 'users', 
 
      $my->usertype, 'components', 'com_newsfeeds' ))) {
         mosRedirect( 'index2.php', _NOT_AUTH );
}

Pierwsza linia jest nam już znana z opisu poprzedniego pliku. Kolejne linie sprawdzają, czy użytkownik otwierający ten plik, ma uprawnienia administratora.

     require_once( $mainframe->getPath( 'admin_html' ) );
     require_once( $mainframe->getPath( 'class' ) );

Teraz wczytujemy pliki admin.dailymessage.html.php and dailymessage.class.php. Funkcja getPath() zwraca odpowiednie ścieżki i nazwy plików.

 
     $id = mosGetParam( $_REQUEST, 'cid', array(0) );
          if (!is_array( $id )) {
          $id = array(0);
     }

Lista wiadomości dnia (jak i większość głównych stron administracyjnych komponentów) posiada po lewej stronie zestaw checkboxów pod nazwą zaczynającą się na 'cid'. Funkcja mosGetParm() zwraca nam wszystkie te checkboxy w tablicy $id. Jeśli taka tablica jest niedostępna (np. gdy strona ładuje się pierwszy raz), $id ustawia się na pustą tablicę, co pozwala na unikniecie ewentualnych błędów w przetwarzaniu.

     switch($act) {
 
         case "configure":
               switch($task) {
                    case "save":
                         saveConfiguration($option);
                         break;
                default:
                         listConfiguration($option);
                         break;
               }
          break;
          default:
 
     switch ($task) {
               case "save" :
                    save($option);
               break;
               case "edit" :
                    edit( $option, $id );
               break;
               case "new" :
                    $id = '';
                    edit( $option, $id);
               break;
 
               case "delete" :
                    del($option, $id);
               break;
 
               case "publish" :
                    publishMessage($option, '1', $id);
               break;
 
               case "unpublish" :
                    publishMessage($option, '0', $id);
               break;
 
               case "listMessages" :
               default:
                    listMessages($option);
               break;
 
               }
          break;
      }

Teraz jest dobry moment do omówienia różnic pomiędzy zmiennymi $task i $act. Kiedy administrator klika na przycisk ’Zapisz’ lub ’Publikuj’, wybór ten musi zostać przekazany do komponentu, dokonuje się to poprzez zmienną $task . Dodatkowo ikony te mogą być użyte w różnych podmenu komponentu. Komponent musi dokładnie wiedzieć, o którą funkcjonalność nam chodzi. Wtedy właśnie używamy zmiennej $act. W naszym przypadku komponent Daily Message (Wiadomość Dnia) ma dwa podmenu : Edit Messages (Edytuj Wiadomośći) oraz Config (Konfiguruj). Podmenu te są identyfikowane, przez $act jako odpowiednio ’all’ oraz ’configure’.

Komponent Daily Message (Wiadomość Dnia) używa zagnieżdżonych poleceń switch, aby stwierdzić, jaką akcję powinien podjąć. Zewnętrzny switch bazuje na zawartości zmiennej $act, ponieważ oba podmenu ’all’ i ’configure’ używają takich samych zadań ($task). Tak więc najpierw sprawdzamy zmienną $act a potem zmienną $task.

Uwaga!Użycie poleceń switch dokładnie odzwierciedla menu komponentu w panelu administratora oraz pasek narzędzi (toolbar) w każdym z podmenu. W przypadku znalezienia odpowiedniego $task jesteśmy odsyłani do funkcji obsługującej dane zdarzenie. Funkcje zdefiniowane są w tym samym pliku.

function saveConfiguration($option) {
     global $database;
     $row = new joeDailyMessageConf($database);

Teraz zdefiniujemy funkcje obsługujące różne zadania. Pierwsza z nich zapisze w bazie danych ustawienia, kiedy klikniesz na przycisku ’Zapisz’ na stronie konfiguracji komponentu. Parametrem funkcji jest zmienna $option ustawiona przez Mambo na nazwę komponentu, którego dotyczy akcja, w naszym przypadku to ’com_dailymessage’. Pozwoli nam to zakodować później przekierowanie powrotne do panelu administracyjnego komponentu. Następna linia jest nam znana. Powoduje, że obiekt bazy danych jest dostępny w funkcji. Deklarujemy nowy obiekt $row typu joeDailyMessageConf (klasa zdefiniowana w pliku dailymessage.class.php), który jest rozszerzeniem standardowej klasy w Mambo - mosDBTable. Obiekty bazujące na mosDBTable mają wiele funkcji ułatwiających proces zapisywania informacji w bazie danych.

// bind it to the table
     if (!$row -> bind($_POST)) {
          echo "<script> alert('"
          .$row -> getError()
          ."'); window.history.go(-1); </script>\n";
          exit();
     }

Ten fragment używając odziedziczonej z klasy mosDBTable funkcji bind(), próbuje uzyskać wartości z tablicy _POST i przypisać je do odpowiednich zmiennych obiektu $row. Jeśli próba jest nieudana (np., nazwy zmiennych nie pasują lub ich typ jest się nie zgadza), przy użyciu Javascript wyświetlany jest błąd i wykonanie dalszego kodu jest zatrzymane. Bład pojawia się jako okienko popup wraz z przyciskiem przekierowującym nas do poprzedniej strony.

Uwaga!To przypisanie to próba spasowania wszystkich zmiennych przekazanych jako parametry HTML-owego formularza do kolumn tablicy bazie danych. Czyli wyobraźcie sobie, że zmieniacie ustawienia konfiguracyjne wpisując/zmieniając dane w odpowiednim formularzu HTML a potem chcąc zapisać te dane są one przekazane tutaj w tablicy _POST pod odpowiednimi nazwami odpowiadającymi nazwom kolumn tabeli konfiguracyjnej komponentu w bazie danych.

// store it in the db
     if (!$row -> store()) {
          echo "<script> alert('"
          .$row -> getError()
          ."'); window.history.go(-1); </script>\n";
     exit();
     }

Kiedy już spasowaliśmy wszystkie informacje i przechowujemy je w obiekcie $row, to możemy zapisać je do bazy danych, używając funkcji store(). Obsługa ewentualnych błędów jest analogiczna do powyższego fragmentu.

     mosRedirect("index2.php?option=$option&act=configure", "Configuration Saved");
 }

Na zakończeniu, jeśli powiodły się wszystkie poprzednie kroki, użytkownik jest przekierowywany z powrotem do strony konfiguracyjnej komponentu oraz na górze strony wyświetlany jest komunikat 'Configuration Saved' (Ustawienia Zapisane). Zmienna $option, zawiera informacje przekazaną jako parametr (com_dailymessage) i powiadamia, Mambo, aby otworzyło teraz panel administracyjny komponentu Daily Message (Wiadomość Dnia). Zauważcie, że odnośnik zawiera zmienną $act ustawioną na 'configure'. Jeśli by tego tam nie było, użytkownik zostałby przekierowany do domyślnej strony administracyjnej komponentu, czyli w naszym przypadku: edycja wiadomości.

function listConfiguration($option) {
     global $database;
 
     $database->setQuery("SELECT * FROM #__joe_dailymessage_conf"  );
     $rows = $database -> loadObjectList();

Kolejna funkcja obsługuje wyświetlanie ustawień. Odczytuje aktualną konfigurację komponentu z bazy danych i wyświetla ją na formularzu, gdzie ustawienia mogą być edytowane według potrzeb administratora. Odpowiednie zapytanie jest skierowane do bazy danych, a jego wynik zapisujemy w obiekcie $rows. Szczegóły opisałem w powyższej funkcji.

     if ($database -> getErrorNum()) {
          echo $database -> stderr();
          return false;
     }

Jeżeli wystąpił błąd podczas przetwarzania zapytania do bazy danych, ten fragment kodu wyświetli przyczynę błędu oraz zatrzyma funkcję, aczkolwiek pozwoli Mambo na zakończenie ładowania strony bez danych konfiguracyjnych pobranych z bazy danych.

 
     HTML_joeDailyMessage::listConfiguration($option, $rows);
     }

Tutaj następuje wywołanie funkcji listConfiguration z obiektu HTML_joeDailyMessage, który zdefiniowaliśmy w pliku admin.dailymessage.html.php. Parametrami są nazwa komponentu ($option) oraz dane konfiguracyjne pobrane z bazy danych ($rows).

Uwaga!Wywoływana tutaj funkcja ma za zadanie wygenerować kod HTML budujący formularz oraz wypełnić go danymi.

function publishMessage( $option, $publish=1 ,$cid ) {
   global $database, $my;
    if (!is_array( $cid ) || count( $cid ) < 1) {
       $action = $publish ? 'publish' : 'unpublish';
       echo "<script>alert('Select an item to $action'); window.history.go(-1);</script>\n";
       exit;
    }

Kiedy administrator chce opublikować wiadomość, ta funkcja ustawia znacznik 'publikacja' tej wiadomości. Musimy najpierw sprawdzić, czy administrator wybrał jakąś wiadomość do publikacji

Uwaga!(w opisie poprzedniego pliku objaśniłem, co to jest tablica $cid, jest to zbiór zaznaczonych checkboxsów po lewej stronie panelu administracyjnegokomponentu).
Jeżeli administrator nie zaznaczył żadnej wiadomości do opublikowania, wyświetlamy odpowiedni komunikat w Javascript i wysyłamy go do poprzedniej strony. Wiersz gdzie przypisujemy wartość zmiennej $action jest skróconą wersją polecenia 'if'. Zmiennej $action przypisujemy napis ’publish’ jeśli zmienna $publish równa się 1, w przeciwnym przypadku zmiennej $action przypisujemy napis ’unpublish’.

     $cids = implode( ',', $cid );

Jeśli administrator wybrał kilka wiadomości do publikacji, tworzymy zmienną $cids, która zawiera listę wartości z tablicy $cid rozdzielonych przecinkiem. Zabieg ten ułatwi nam aktualizację bazy danych.

     $database->setQuery( "UPDATE #__joe_dailymessage SET published='$publish'"
     . "\nWHERE id IN ($cids)"
);
     if (!$database->query()) {
          echo "<script> alert('".$database->getErrorMsg()."'); 
             window.history.go(-1); </script>n";
          exit();
     }

Zapytanie aktualizuje bazę danych informacją o publikacji/niepublikowaniu. Jakiekolwiek błędy towarzyszące zapytaniu są wyświetlane poprzez Javascript.

     mosRedirect( "index2.php?option=$option" );
 }

W ostatnim kroku administrator jest przekierowywany do domyślnej strony administracyjnej komponentu przekazanego w zmiennej $option, czyli ’com_dailymessage’.

function save($option) {
     global $database;
 
     $row = new joeDailyMessage($database);
 
// bind it to the table
     if (!$row -> bind($_POST)) {
          echo "<script> alert('"
          .$row -> getError()
          ."'); window.history.go(-1); </script>\n";
          exit();
     }
 
// store it in the db
    if (!$row -> store()) {
        echo "<script> alert('"
        .$row -> getError()
        ."'); window.history.go(-1); </script>\n";
        exit();
    }
    mosRedirect("index2.php?option=$option", "Saved");
    }

Funkcja jest prawie identyczna do funkcji saveConfiguration, różnica polega na użyciu innego typu obiektu - joeDailyMessage oraz przekierowaniu do domyślnej strony administracyjnej komponentu (edytowanie wiadomości) wraz z wiadomością ’Saved’ (Zapisane).

Uwaga!Po prostu zapisujemy inne informacje i dlatego musimy użyć obiektu odzwierciedlającego dane z tablicy z wiadomościami. Pozostała funkcjonalność jest taka sama, polecam więc analizę funkcji saveConfiguration.

function del($option, $cid) {
    global $database;
 
    if (!is_array($cid) || count($cid) < 1) {
        echo "<script> alert('Select an item to delete'); window.history.go(-1);</script>\n";
        exit();
    }

Lista wiadomości do skasowania jest przekazana jako parametr tej funkcji. Jeśli parametr nie jest tablicą lub nie zawiera elementów, odpowiedni komunikat jest wyświetlany i administrator jest przekierowany do poprzedniej strony.

    if (count($cid)) {
        $ids = implode(',', $cid);
        $database->setQuery("DELETE FROM #__joe_dailymessage WHERE id IN ($ids)");
    }

Sprawdzając po raz kolejny, że wybrane zostały wiadomości do skasowania, tworzymy zapytanie do bazy danych powodujące ich skasowanie.

    if (!$database->query()) {
        echo "<script> alert('"
        .$database -> getErrorMsg()
        ."'); window.history.go(-1); </script>\n";
    }
    mosRedirect("index2.php?option=$option");
   }

Zapytanie kasujące jest wykonywane wraz ze standardową obsługą ewentualnych błędów. Następuje przekierowanie do domyślnej strony administracyjnej komponentu.

function edit($option, $uid) {
    global $database;
 
    if($uid){
        $row = new joeDailyMessage($database);
        $row -> load($uid[0]);
    }

Jeśli administrator wybierze wiadomość do edycji, ta funkcja tworzy odpowiedni obiekt odpowiadający kolumnom tabeli z wiadomościami oraz wypełnia go informacjami przekazanymi w parametrze $uid. Ponieważ edytujemy jedną wiadomość na raz, szukane informacje są w pierwszym wierszu tablicy $uid ($uid[0]). Przekazujemy je do obiektu $row.

    HTML_joeDailyMessage::edit($option, $row);
    }

Wywołujemy funkcję edit z klasy HTML_joeDailyMessage, która generuje odpowiedni formularz HTML i wypełnia go danymi z obiektu $row.

function listMessages($option) {
    global $database;
 
    $database->setQuery("SELECT * FROM #__joe_dailymessage ORDER BY id"  );

Ostatnia funkcja wyświetla domyślną strone administracyjną komponentu. Jeśli nie wybierzesz żadnego zadania ($task), ta funkcja wyświetli wszystkie Wiadomości Dnia pozwalając administratorowi na ich edycje, kasowanie, publikacje/nie publikacje. Zapytanie pozwala odczytać całą zawartość tablicy z wiadomościami dnia. Są one posortowane według identyfikatora, który w bazie danych jest ustawiony na autozwiększanie. W ten sposób możemy stworzyć unikatowy klucz w bazie danych oraz wyświetlić wiadomości według ich kolejności powstania.

    $rows = $database -> loadObjectList();
        if ($database -> getErrorNum()) {
        echo $database -> stderr();
    return false;
    }
    HTML_joeDailyMessage::listMessages($option, $rows);
 }
?>

Wykonujemy zapytania, wyświetlamy na stronie wynikowej wszystkie ewentualne błedy. Funkcja listMessages() w klasie HTML_joeDailyMessage wygeneruje kod HTML pokazujący wszystkie wiadomości na stronie.

<?php
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

Tę linię już powinniśmy dobrze znać, zapewnia, że plik nie zostanie wywołany spoza środowiska Mambo.

class HTML_joeDailyMessage{

Ta klasa jest używana w pliku amin.dailymessage.php i obsługuje generowanie kodu HTML po stronie administratorskiej komponentu.

 
function edit( $option, &$row ) {

Parametrami tej funkcji jest nazwa komponentu ($option, w naszym przypadku jest to 'com_dailymessage') oraz wiersz z danymi pobrany z bazy danych w pliku admin.dailymessage.php. Funkcja powoduje wygenerowanie formularza, w którym można edytować przekazaną jako parametr ($row) Wiadomość Dnia. Warto zauważyć, że parametr $row jest przekazywany jako wskaźnik (&$row), pozwala to na przekazywanie dużych ilości danych poprzez odwołanie do danych istniejących już w środowisku php, a nie tworzenie ich kopii w kolejnej instancji obiektu.

?>
 
<form action="index2.php" method="post" name="adminForm" id="adminForm" class="adminForm">
<table border="0" cellpadding="3" cellspacing="0">
 
<tr>
<td>Message: </td><td><input type="text" size="50" maxsize="100" name="message" 
     value="<?php echo $row->message; ?>" /></td></tr>
 
<tr>
<td>Date: </td><td><input size="30" name="date" 
     value="<?php echo $row->date; ?>"></td></tr>
 
<tr>
<td>Published: </td><td><?php echo mosHTML::yesnoSelectList( "published", "", $row->published ); ?></td></tr>

Jeśli dane z bazy danych zostały z powodzeniem załadowane to teraz wypełnią budowany formularz. Proszę zauważyć, że kolumna ’Published’ jest obsługiwana przez funkcję yesnoSelectList klasy mosHTML. Klasa ta jest zadeklarowana w pliku classes/mambo.php i dostępna w całym środowisku Mambo. Funkcja ta generuje rozwijaną listę z dwiema wartościami ’Tak’ i ’Nie’. Jeśli wartość zmiennej $row->Publisher równa się '0', ’Nie’ będzie wybrane na liście. Jeśli wartością będzie '1', na liście wybrane będzie ’Tak’. Funkcja ta może być bardzo pomocna w wielu formularzach administracyjnych i używa się ją znacznie przyjemniej niż checkboxy.

Uwaga!Powyższy kod to praktycznie czysty HTML, więc nie będę się zagłębiał w jego wyjaśnianie. Osobiście polecam zapoznanie się z klasą mosHTML, która zawiera więcej podobnie pożytecznych funkcji. Jej opis znajdziecie w dokumentacji Mambo na oficjalnych stronach (niestety w języku angielskim)
.

 
</table>
<input type="hidden" name="id" value="<?php echo $row->id; ?>" />
<input type="hidden" name="option" value="<?php echo $option; ?>" />
<input type="hidden" name="task" value="" />
</form>
<?php }

Formularz kończymy definicją kilku niezbędnych zmiennych ukrytych, zawierających identyfikator Wiadomości Dnia ('id'), nazwę komponentu ('option') oraz wykonywane zadanie ('task'). Zmienne te są wysłane razem z pozostałymi polami formularza po zakończeniu edycji. Zmienna zadanie ('task') jest ustawiana na pustą tak, aby później mogła zostać wypełniona przez Javascript w zależności od tego na jaki przycisk w pasku narzędzi kliknie administrator.

function listConfiguration($option, &$rows){

Ta funkcja jest używana, gdy administrator chce wyświetlić ustawienia konfiguracyjne komponentu Wiadomość Dnia (Daily Message).

?>
<form action="index2.php" method="post" name="adminForm">
 
<table cellpadding="4" cellspacing="0" border="0" width="100%" class="adminlist">
<?php
$row = $rows[0];
?>
<tr><td>Bold</td><td>
   <?php echo mosHTML::yesnoSelectList( "bold", "", $row->bold ); ?></td></tr>
<tr><td>Italic</td><td>
   <?php echo mosHTML::yesnoSelectList( "italic", "", $row->italic ); ?></td></tr>
<tr><td>Underline</td><td>
   <?php echo mosHTML::yesnoSelectList( "underline", "", $row->underline ); ?></td></tr>
<tr><td>Show Date</td><td>
   <?php echo mosHTML::yesnoSelectList( "showdate", "", $row->showdate ); ?></td></tr>
</table>

Formularz jest wypełniany danymi z pierwszego (i jedynego) wiersza tabeli mos_joe_dailymessage_conf przekazanymi w parametrze $rows (znowu jako wskaźnik). Jak widać użycie funkcji yesnoSelectList ułatwia wyświetlanie, edytowanie oraz zapewnia, że nie zostaną wprowadzone bzdurne dane.

<input type="hidden" name="option" value="<?php echo $option; ?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="configid" value=<?php echo $row->configid ?> />
<input type="hidden" name="act" value="configure" />
</form> 
<?
}

Ponownie zmienne nazwa komponentu ('option'), identyfikator ustawień ('configid') oraz podmenu ('act') są ukrywane na końcu formularza. Zmienna identyfikator ustawień ('configid') zapewnia że edytujemy jeden i ten sam wiersz z ustawieniami (aczkolwiek powinien być tylko jeden). Zmienna podmenu ('act') przekazuje do pliku admin.dailymessage.php, że chcemy zapisać albo anulować zmiany w konfiguracji komponentu, a nie w jego wiadomościach. Jest obsługiwane poleceniami switch na samym początku pliku admin.dailymessage.php.

function listMessages( $option, &$rows ) {
 ?>

Ostatnia z funkcji tworzy domyślną stronę panelu administracyjnego lub uaktywnia się po kliknięciu w przycisk Edycja Wiadomości.

<form action="index2.php" method="post" name="adminForm">
 
<table cellpadding="4" cellspacing="0" border="0" width="100%" class="adminlist">
<tr>
<th width="20"><input type="checkbox" name="toggle" value=""      
     onclick="checkAll(<?php echo count($rows); ?>);" /></th>  <th class="title" width="25%">Message</th>  <th>Date</th>  <th width="25%">Published</th></tr>

Tutaj mamy definicje nagłówków w tabeli wraz z głównym checkboxem, który użyty zaznacza wszystkie Wiadomości Dnia.

Uwaga!Warto zauważyć, że przy tworzeniu takiej tablicy posługujemy się klasą CSS adminlist dostępną w środowisku Mambo. Pozwala to na zachowanie jednolitego wyglądu stron administracyjnych wszystkich komponentów.

<?php
$k = 0;
for($i=0; $i < count( $rows ); $i++) {
$row = $rows[$i];
   ?>

Tutaj zaczyna się pętla, która przechodzi przez wszystkie Wiadomości Dnia przechowywane w bazie danych, czyli wszystkie wiersze tablicy $rows.

<tr class="<?php echo "row$k"; ?>">

Tutaj używamy zdefiniowanego w Mambo stylu CSS, który powoduje że wyświetlane wiersze są w zebrę, na przemian z tłem białym i szarym, co ułatwia przeglądanie informacji.

<td><input type="checkbox" id="cb<?php echo $i;?>" 
   name="cid[]" value="<?php echo $row->id; ?>" 
   onclick="isChecked(this.checked);" /></td>

Teraz po lewej stronie każdej wyświetlanej pozycji na liście wszystkich Wiadomości Dnia wyświetlamy checkbox, który pozwala nam zaznaczyć Wiadomość do edycji / usunięcia itp. Identyfikatory chceckboxów są przechowywane w zmiennych $cbX, gdzie X jest numerem pozycji na liście. Identyfikatory tworzą tablice a ich wartości są ustawiane na wartości identyfikatora Wiadomości (id) pobrany z bazy danych.

<td><a href="http://www.pomoc.joomla.pl/content/view/67/30/#edit" 
      onclick="return listItemTask('cb<?php echo $i;?>','edit')">
   <?php echo $row->message; ?></a></td> 

Powyższy kod tworzy link zawierający treść Wiadomości Dnia. Kliknięcie na link spowoduje automatyczne zaznaczenie checkboxu po lewej stronie oraz powiadomi Javascript aby wykonać formularz z zadaniem (task) edycji ('edit').

 
<td><?php echo mosFormatDate($row->date); ?></td>

Wyświetlamy date powstania wiadomości, data pokazywana jest w zależności od lokalnych ustawień Mambo, dzięki uzyciu funkcji mosFormatDate, która jest zadeklarowana w pliku classes/mambo.php

<td align="center">
      <?php
if ($row->published == "1") {
echo "<a href="javascript: void(0);" onClick="return listItemTask('cb$i','unpublish')">
   <img src="images/publish_g.png" border="0" /></a>";
} else {
echo "<a href="javascript: void(0);" onClick="return listItemTask('cb$i','publish')">
   <img src="images/publish_x.png" border="0" /></a>";
}
      ?>
     </td>

Teraz wyświetlamy ikonę 'published' lub 'unpublished', w zależności od statusu wiadomości. Klikniecie na ikonę spowoduje, że nadamy wiadomości przeciwny status.

Uwaga!Ja osobiście zmieniłem powyższy kod na kod podejrzany w komponencie Mambo Banners
:

      <?php
        $task=$row->published ? 'unpublish' : 'publish';
        $img=$row->published ? 'publish_g.png' : 'publish_x.png';
        $alt=$row->published ? (_CMN_PUBLISHED) : (_CMN_UNPUBLISHED);
      ?>
      <td align="center"><a href="javascript: void(0);" onClick="return      
             listItemTask('cb<?php echo $i;?>','<?php echo $task;?>')">
<img src="images/<?php echo $img;?>" 
     width="12" height="12" border="0" alt="<?php echo $alt; ?>" /></a></td>

Uwaga!Z jakiś powodów ten kod wydaje mi się bardziej przejrzysty. Przy okazji macie okazje zobaczyć, że jedną i tą samą rzecz można zrobić na kilka sposobów. Dodatkowo zachęcam tutaj do przeglądania istniejących komponentów w Mambo. Jak tylko zrozumiecie, jak działa komponent, przeglądanie kodu i jego analiza będzie bardzo przyjemna.

 
<?php $k = 1 - $k; ?>

Zmieniamy wartość zmiennej, która determinuje wygląd wiersza na liście.

Uwaga!Przyjmuje ona wartość 0 lub 1 i w zależności od niej używamy naprzemian innych stylów do wyświetlania wiersza danych na liście.

</tr>
<?php } 
?>
<input type="hidden" name="option" value="<?php echo $option; ?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
</form> 
</table>
 
<? } 
 
}

Po raz kolejny ukrywamy zmienne komponent('option'), zadanie ('task') oraz zaznaczony checkbox ('boxchecked'). Oba zadanie oraz zaznaczony checkbox są później wypełniane przez Javascript. Zaznaczony checkbox ('boxchecked') jest używany do sprawdzenia czy wybraliśmy jakieś pozycje na liście przed podjęciem dalszych działań.

?>

dailymessage.class.php

<?php
 defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

Sprawdzamy czy plik jest wywoływany z środowiska Mambo.

class joeDailyMessage extends mosDBTable {
var $id = null;
var $message = null;
var $date = null;
var $published = null;

Ta klasa jest rozszerzeniem klasy, mosDBTable, która dostarcza wielu użytecznych funkcji wspomagających współpracę z bazą danych. Musimy zadeklarować zmienne identyczne w nazwie do kolumn w tablicy. W ten sposób w innych fragmentach kodu komponentu możemy tworzyć obiekt joeDailyMessage, wypełnić / załadować danymi i zapisać w bazie danych.

function joeDailyMessage(&$db){
$this->mosDBTable('#__joe_dailymessage', 'id', $db);
}
 
}

Ten konstruktor używając wskaźnika do bazy danych przekazanego jako parametr, przesyła go do konstruktora klasy mosDBTable, wraz z nazwą tablicy (przypominam, że prefix '#_' jest zamieniony na prefix bazy danych zdefiniowany w ustawieniach Mambo) oraz nazwą pola będącego kluczem tablicy.

Uwaga!Istotne w tworzeniu takiej klasy jest dokładne powielenie nazw zmiennych w tablicy poprzez zadeklarowanie ich tutaj. Funkcja konstruktor jest standardowa i oprócz nazwy tablicy i klucza nic nie powinno się tu zmieniać. Jak widzicie, Mambo zakłada, że każda z używanych przez nas tablic posiada klucz (unikalną zmienną w tablicy, która zawsze jednoznacznie identyfikuje wiersz danych.

class joeDailyMessageConf extends mosDBTable {
var $bold = null;
var $italic = null;
var $underline = null;
var $showdate = null;
var $configid = null;
 
function joeDailyMessageConf(&$db){
$this->mosDBTable('mos_joe_dailymessage_conf', 'configid', $db);
}
}

Klasa joeDailyMessageConf jest zdefiniowana w ten sam sposób co powyższa klasa joeDailyMessage. Różnica polega na zadeklarowaniu innych zmiennych, odpowiadających zmiennym w tablicy mos_joe_dailymesssage_conf. W funkcji konstruktorze mamy tez użyte inne parametry, nazwę tablicy i zmienną klucz.

?>

Dla wszystkich komponentów Mambo ładuje kod paska narzędzi w panelu administracyjnym. Tworzenie takiego kodu jest bardzo przejrzyste, ponieważ funkcjonalność ta jest bardzo dobrze zdefiniowana. Kod w tym pliku jest de facto jednym poleceniem wyboru 'switch', które ładuje odpowiedni pasek narzędzi w zależności od wartości zmiennych zadanie 'task' oraz podmenu 'act'.

<?php
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
require_once( $mainframe->getPath( 'toolbar_html' ) );

Tradycyjnie, musimy się upewnić, że tylko Mambo użyje tego pliku. ładujemy również kod z pliku toolbar.dailymessage.html.php, który odpowiada za generacje kodu HTML tworzącego pasek narzędzi.

Uwaga!Czyli analogicznie jak w stronach administracyjnych mamy tutaj plik odpowiedzialny za logikę paska narzędzi i drugi, który generuje kod HTML. Ten schemat ułatwia prace nad komponentem i pozwala na niezależną prace nad obiema warstwami wszystkich elementów panelu administracyjnego komponentu.

switch ( $task ) {
case 'edit':
menuDailyMessage::EDIT_MENU();
break;
 
case 'new':
menuDailyMessage::EDIT_MENU();
break;
 
default:
switch($act)
{
case "configure":
menuDailyMessage::CONFIGURE_MENU();
 
break;
 
default:
menuDailyMessage::DEFAULT_MENU();
break;
}
break;
 
}

Proszę zauważyć, że oba zadania nowy 'new' i edycja 'edit' współdzielą ten sam pasek narzędzi. Nie powoduje to konfliktu, ponieważ pasek narzędzi tylko wywołuje zadanie i nie jest funkcjonalnie zależny od bieżącego zadania. Bieżące zadanie oraz podmenu 'act' determinują, które opcje będą wyświetlane w pasku narzędzi. Wszystkie paski narzędzi są wyświetlane przy użyciu funkcji klasy menu DailyMessage zadeklarowanej w pliku toolbar.dailymessage.html.php .

Uwaga!Podobnie jak w pliku z logiką panelu administracyjnego, badając zawartość zadania 'task' oraz podmenu 'act' wyświetlamy odpowiednie paski narzędzi. Paski zawierają zadania, jakie możemy wykonać na danej stronie administracyjnej komponentu.

?>

Plik definiuje klasę menuDailyMessage , która zawiera 3 funkcje generujące 3 różne paski narzędzi. Paski narzędzi są generowane przy użyciu funkcji klasy mosMenuBar, standardowej klasy Mambo obsługującej wszystkie paski narzędzi.

<?php
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

Nie zapomnijmy jak zawsze o zabezpieczeniu przed bezpośrednim uruchomieniem kodu.

class menuDailyMessage{
function DEFAULT_MENU() {
mosMenuBar::startTable();
mosMenuBar::publish('publish');
mosMenuBar::unpublish('unpublish');
mosMenuBar::divider();
mosMenuBar::addNew('new');
mosMenuBar::editList('edit', 'Edit');
mosMenuBar::deleteList( ' ', 'delete', 'Remove' );
mosMenuBar::endTable();
}

Dla większości użytych tu funkcji pierwszym parametrem jest nazwa zadania 'task'. Dla funkcji deleteList(), pierwszym parametrem jest opcjonalny alternatywny tekst ostrzeżenia, jakie się pojawi, gdy będziesz cos usuwał. Drugi parametr to nazwa zadania 'task' a ostatni to opcjonalny tekst alternatywny, jaki pojawi się po najechaniu na ikonę 'usuń' w panelu narzędzi. Ta funkcjonalność jest możliwa także w innych funkcjach.

Uwaga!Polecam przegląd dokumentacji o tej klasie, jest tam więcej funkcji do użycia i wiele więcej parametrów.
Funkcje startTable() oraz endTable() generują początek i koniec HTML tabelki paska narzędzi wraz z dodatkowym kodem Javascript obsługującym przyciski. Funkcja divider() wyświetla standardowy separator ikon.

function EDIT_MENU() {
mosMenuBar::startTable();
mosMenuBar::back();
mosMenuBar::spacer();
mosMenuBar::save('save');
mosMenuBar::endTable();

Funkcja back() wyświetla przycisk ’Anuluj’ (cancel). Kliknięty powoduje powrót do poprzedniej strony. Funkcja spacer() generuje dodatkowe puste miejsca pomiędzy przyciskami.

}
function CONFIGURE_MENU() {
mosMenuBar::startTable();
mosMenuBar::save('save');
mosMenuBar::endTable();
}
}
?>

Funkcjonalność powyższych plików polega na wygenerowaniu standardowych komunikatów instalacyjnych i deinstalacyjnych. Nasz komponent nie potrzebuje żadnych dodatkowych akcji.

install.dailymessage.php:

<?php
function com_install() {
}
?>

uninstall.dailymessage.php:

<?php
function com_uninstall() {
}
?>

Uwaga!Plik zawierający informacje o komponencie oraz definiujący elementy składowe komponentu. Używany do instalacji oraz deinstalacji.

<?xml version="1.0" ?>

Ten znacznik definiuje wersje XML używaną w tym pliku. Większość stosowanych plików XML używa wersji 1.0. Jeśli chcecie dowiedzieć się więcej o XML poczytajcie sobie na stronach www.w3c.org (angielski).

<mosinstall type="component">

Tutaj informujemy Mambo, jakie rozszerzenie będziemy instalować. Kod obsługujący instalacje komponentu różni się od tego potrzebnego do instalacji modułu lub szablonu graficznego (template).

<name>DailyMessage</name>
<creationDate>06/03/2004</creationDate>
<author>Joseph LeBlanc</author>
<copyright>This component in released under the GNU/GPL License</copyright>
<authore-mail>contact @ jlleblanc.com</authore-mail>
<authorUrl>www.jlleblanc.com</authorUrl>
<version>1.0</version>

Te znaczniki definiują nazwę komponentu, datę powstania, autora, prawa użytkowania, e-mail autora, jego adres strony domowej oraz numer wersji komponentu. Te informacje są później widoczne w części zarządzania komponentami w Mambo. Nazwa komponentu zostanie użyta do stworzenia katalogu com_[nazwa_komponentu]. Nie powinna zawierać spacji oraz innych specjalnych znaków.

Uwaga!Oprócz tego, ze powstanie taki katalog, tutaj definiujemy jak będzie się identyfikował nasz komponent w środowisku Mambo. Tak, więc wartość com_[nazwa_komponentu] będzie używana do identyfikacji naszego komponentu.

<files>
<filename>dailymessage.php</filename>
</files>

Znacznik pliki <files> zawiera listę plików używanych do obsługi wizualnej strony komponentu, (czyli to, co będzie widział odwiedzający nasz strony). Każdy z nich zawarty jest w znaczniku nazwa pliku <filename>. W naszym przypadku, używamy tylko jednego pliku.

Uwaga!Jeśli po stronie wizualnej chcemy używać własnych plików graficznych to zostają one zadeklarowane również tutaj np. <filename>images/grafika.png. Powstanie podkatalog components/com_[nazwa_komponentu]/images/ i tam zostanie zapisany nasz plik graficzny.

<install>
<queries>
<query>
DROP TABLE IF EXISTS `# __joe_dailymessage`;
</query>
<query>
CREATE TABLE `# __joe_dailymessage` (
`id` INT NOT NULL AUTO_INCREMENT,
`message` TEXT NOT NULL,
`date` DATETIME NOT NULL,
`published` TINYINT(1) NOT NULL,
PRIMARY KEY (`id`)
)
</query>
<query>
DROP TABLE IF EXISTS `# __joe_dailymessage_conf`;
</query>
<query>
CREATE TABLE `# __joe_dailymessage_conf` (
`bold` TINYINT(1) NOT NULL,
`italic` TINYINT(1) NOT NULL,
`underline` TINYINT(1) NOT NULL,
`showdate` TINYINT(1) NOT NULL,
`configid` TINYINT(4) NOT NULL
)
</query>
<query>
INSERT INTO `# __joe_dailymessage_conf`
   (bold, italic, underline, showdate, configid) values(0, 0, 0 , 1, 1);
</query>
</queries>
</install>

W znacznikach instalacja <install> zawieramy polecenia do bazy danych wymagane dla utworzenia tablic naszego komponentu. Polecenia umieszczamy w znacznikach zapytanie <query>. Prefix '#_' zostanie zastąpiony poprzez prefix tablic Mambo zdefiniowany w ustawieniach portalu (standardowo 'mos'). Tworzymy 2 tablice: jedna dla przechowywania Wiadomości Dnia i druga do przechowywania ustawień komponentu. Dodatkowo wprowadzamy standardowe ustawienia komponentu.

Uwaga!Proszę zauważyć, że dla pewności najpierw staramy się usunąć tablice z bazy danych a potem ją tworzymy. Zapewnia to bezpieczne instalacje po jakiś nieudanych eksperymentach.

<uninstall>
<queries>
<query>
DROP TABLE IF EXISTS `# __joe_dailymessage`;
</query>
<query>
DROP TABLE IF EXISTS `# __joe_dailymessage_conf`;
</query>
</queries>
</uninstall>

Analogicznie do znaczników instalacyjnych definiujemy znaczniki deinstalacyjne <uninstall>. Pomiędzy nimi definiujemy polecenia do bazy danych niezbędne do usunięcia tabel używanych przez nasz komponent.

<installfile>
<filename>install.dailymessage.php</filename>
</installfile>
 
<uninstallfile>
<filename>uninstall.dailymessage.php</filename>
</uninstallfile>

Znaczniki plik instalacyjny <installfile> oraz plik deinstalacyjny <uninstallfile> zawierają nazwy plików obsługujących dodatkowe czynności związane z instalacją / deinstalacją komponentu. Pliki te zostaną skopiowane do katalogu administrator/com_dailymessage.

<administration>
<menu>Daily Message</menu>
<submenu>
<menu act="all">Edit Messages</menu>
<menu act="configure">Configure</menu>
</submenu>

Znacznik administracja <administration> zawiera wszystkie informacje niezbędne do obsługi panelu administracyjnego komponentu. Znacznik <menu> definiuje tytuł menu komponentu, jaki pojawi się w menu administracyjnym ’Komponenty’. Znaczniki podmenu <submenu> definiują podmenu menu komponentu. Tutaj również zdefiniowana jest wartość zmiennej podmenu 'act', która umożliwia zdeterminowanie podmenu do wyświetlenia.

Uwaga!Tutaj waśnie buduje się menu komponentu, które widzimy po stronie administracyjnej Mambo. Wartości zmiennej podmenu 'act' są używane w plikach obsługujących logikę strony administracyjnej komponentu.

<files>
<filename>admin.dailymessage.php</filename>
<filename>admin.dailymessage.html.php</filename>
<filename>dailymessage.class.php</filename>
<filename>toolbar.dailymessage.php</filename>
<filename>toolbar.dailymessage.html.php</filename>
</files>

Znacznik pliki <files> zawarty wewnątrz znacznika administracja <administrator> wskazuje, które pliki zostaną skopiowane do katalogu administrator/com_dailymessage.

Uwaga!Są to wszystkie pliki niezbędne do obsługi strony administratorskiej komponentu. Jeżeli chcemy użyć tutaj własnych plików graficznych postępujemy tak samo jak opisłaem to powyżej.

</administration>
</mosinstall>

Pytanie, które nurtuje większość nowych użytkowników Mambo. Poznanie odpowiedzi na to pytanie pozwoli bardziej zrozumieć architekturę Mambo. Jaka jest różnica między komponentem a modułem w Mambo?

Krótka odpowiedź: Moduł może pojawiać się na każdej stronie i zazwyczaj ma bardzo prosta funkcjonalność. Komponent generuje swoje własne strony i może być bardzo rozbudowany.

Ta odpowiedź powinna być satysfakcjonująca dla większości z was. Dla bardziej dociekliwych oraz lubiących dogłębnie poznać wspaniałości architektury Mambo jest więcej do odkrycia. Zacznijmy od sposobu, w jaki strony Mambo są generowane.

Kiedy ktoś odwiedza twoje strony, uruchamiany jest plik index.php z głównego katalogu. Ten plik ładuje dużo różnych klas oraz innych fragmentów kodu pozwalających Mambo działać. Po zakończeniu tej fazy, Mambo zerka do katalogu twojego bieżącego szablonu graficznego (templates) i próbuje uruchomić istniejący tam plik index.php. Tak, więc oba katalogi główny oraz szablonu graficznego zawierają pliki index.php - jeden do obsługi technicznej Mambo a drugi do wygenerowania strony graficznej portalu.

Plik index.php w katalogu szablonu graficznego wygląda prawie jak zwyczajny plik HTML. W środku powinieneś znaleźć linie kodu <?php include_once('mainbody.php'); ?>, która informuje PHP aby zaprzestał wyświetlania HTML i wlączył kod z pliku mainbody.php, który ładuje dokładnie jeden komponent. Oznacza to, że każda strona w Mambo używa komponentu (Zgoda, że mógłbyś usunąć tą linijkę kodu i wtedy komponent nie zostanie załadowany, ale to by poważnie uszczupliło funkcjonalność Twojego portalu). Standardowo, Mambo będzie starał się załadować komponent odpowiadający pierwszej pozycji menu głównego. Zazwyczaj jest do ’Home/Start’, który wskazuje na komponent strony głównej 'com_frontpage'. Strona główna wyświetla skróty wiadomości napisanych przez publicystów portalu. Kiedy klikniesz na jednym z linków do pełnej wiadomości, wysyłasz wiadomość do Mambo o załadowaniu komponentu zawartość ’content’, wraz z parametrami konkretnej wiadomości, którą należy pobrać z bazy danych. Inne linki wskazują na inne komponenty.

Poza kodem włączającym plik mainbody.php , twój szablon graficzny będzie miał wiele wywołań funkcji mosLoadModules(), np. mosLoadModules('left'). Ten kod nakazuje Mambo załadować wszystkie moduły przypisane do lewej 'left' pozycji aktualnego komponentu (standardowe pozycje to lewa 'left', prawa 'right', górna 'top', dolna 'bottom', wewnętrzna ’inset’, użytkownika1 ’user1’ oraz użytkownika2 ’user2’). Kiedy edytujesz ustawienia modułu w panelu administracyjnym, możesz wybrać z listy wyboru, do jakich komponentach chcesz przypisać moduł (lub możesz przypisać do wszystkich, co jest standardowym ustawieniem?. W ten sposób administrator może np. przypisać moduł logowania tylko do strony głównej, nie udostępniając go żadnej z podstron. Szablony graficzne nie muszą ładować moduły na każdej z możliwych pozycji (nie muszą wogóle ładować modułów), ale zazwyczaj pomocnym jest załadowanie conajmniej jednego modułu z menu, chyba, że chcesz sam zakodować własną nawigację.

Kiedy ktoś odwiedza Twoje strony prawdopodobnie nie obchodzi go różnica pomiędzy modułem a komponentem. Natomiast, każdy używający panelu administracyjnego do modyfikacji zawartości i układu stron powinien nauczyć się jak zarządzać tymi elementami. Moduły mogą być instalowane z menu Moduły - pozycja instaluj/odinstaluj (install/unisntall). Strona ta wyświetli listę zainstalowanych już modułów wraz możliwością dodania nowych (pod lista).

Kiedy klikniesz na pozycje menu Moduły witryny/administratora będziesz miał widoczna inna listę modułów oraz możliwości publikowania/nie publikowania, ustalenia pozycji oraz układu. Ta lista może być dłuższa od poprzedniej, z uwagi na możliwość tworzenia indywidualnych modułów zawartości ’content’. Te moduły nie są ładowane z kodu katalogu modułów, ale z zawartości bazy danych, podobnie jak wiadomości i artykuły. Widoczne są jak inne moduły.

Wszystkie moduły pozwalają na definiowanie parametrów. Parametry pozwalają twórcy modułu na danie administratorowi możliwości zmiany elementów modułu bez tworzenia skomplikowanego panelu administracyjnego. Spójrzmy na przykład, jeśli twórca modułu chciałby dać administratorowi wpływ na kolor tła modułu, może zdefiniować parametr dostępny w zarządzaniu modułem. Administrator musiałby tylko kliknąć na nazwę modułu i wpisać backgroundcolor="green" (nazwa parametru = parametr) jako pojedyncza linie w polu Parametry ’Parameters’.

Tworzenie panelu administracyjnego komponentu wymaga dużo więcej wysiłku, ale wynikiem jest łatwy w użyciu panel administracyjny komponentu pozwalający zarządzać skomplikowaną funkcjonalnością. Kiedy ładowany jest panel administracyjny komponentu, plik admin.[nazwa_komponentu].php jest wykonywany z katalogu /administrator/component/com_[nazwa_komponentu]. Ten plik generuje odpowiednie strony w zależności od zadania albo podmenu. Dokładnie ten temat omówiliśmy szczegółowo w tym kursie.

Jak tylko zrozumiesz różnice pomiędzy modułem a komponentem, cala struktura Mambo wyda ci się bardzo przejrzysta. Jeśli dobrze się czujesz programując w PHP, powinieneś bez wahań spróbować tworzyć własne moduły i komponenty. Jakkolwiek mądrym posunięciem jest sprawdzenie stron mosforge.net, aby sprawdzić, jakie ogólnie dostępne komponenty i moduły są do dyspozycji. Szanse na znalezienie czegoś o poszukiwanej funkcjonalności są całkiem spore.

Wiele popularnych komponentów Mambo posiada funkcjonalność zakładek na swoich stronach, powodującą logiczny podział dla dużych i skomplikowanych stron. Kod obsługujący zakładki jest częścią środowiska Mambo, gotowy w oczekiwaniu na wykorzystanie w Twoim projekcie!

Uwaga!Przykładem takich zakładek może być strona konfiguracyjna Mambo (menu Witryna/Konfiguracja).

Komponent Wiadomość Dnia (Daily Message) ma stronę konfiguracyjną, która jest pokazywana, gdy klikamy na menu Configure (act='configure'). Plik admin.dailymessage.php rozpoznaje to i przekazuje klasie HTML_joeDailyMessage, aby wykonała funkcje, listConfiguration(), która to generuje HTML wyświetlający opcje konfiguracyjne.

Aczkolwiek oryginalny układ jest miły i przejrzysty, załóżmy, że autor jest zafascynowany zakładkami i chce je użyć również na tej stronie konfiguracyjnej. Bez większego wysiłku, możemy tak zmodyfikować oryginalny kod, aby pojawiły się zakładki:

function listConfiguration($option, &$rows)
{
?>
<form action="index2.php" method="post" name="adminForm">
<table cellpadding="4" cellspacing="0" border="0" width="100%" class="adminlist">
<?
$row = $rows[0];
?>
<tr><td>Bold</td><td><?php echo 
    mosHTML::yesnoSelectList( "bold", "", $row->bold ); ?></td></tr>
<tr><td>Italic</td><td><?php echo 
    mosHTML::yesnoSelectList( "italic", "", $row->italic ); ?></td></tr>
<tr><td>Underline</td><td><?php echo 
    mosHTML::yesnoSelectList( "underline", "", $row->underline ); ?></td></tr>
<tr><td>Show Date</td><td><?php echo 
    mosHTML::yesnoSelectList( "showdate", "", $row->showdate ); ?></td></tr>
</table>
<input type="hidden" name="option" value="<?php echo $option; ?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="configid" value=<?php echo $row->configid ?> />
<input type="hidden" name="act" value="configure" />
</form> 
<?php
}

Jeśli nie pamiętasz o co chodziło w tym kodzie, zapraszam do fragmentu tego kursu objaśniającego plik admin.dailymessage.html.php. Dodajemy zakładki:

function listConfiguration($option, &$rows)
{
?>
<script language="Javascript" src="js/dhtml.js"></script>

Dodajemy skrypt Javascript, który obsługuje funkcjonalność zakładek. Jest on integralną częścią Mambo i wykonuje za nasz większość roboty.

<?
$row = $rows[0];
?>
<table cellpadding="4" cellspacing="0" border="0" width="100%">
<tr>
<td width="" class="tabpadding"> </td><td id="tab1" class="offtab" onClick="dhtml.cycleTab(this.id)">Bold</td><td id="tab2" class="offtab" onClick="dhtml.cycleTab(this.id)">Italic</td><td id="tab3" class="offtab" onClick="dhtml.cycleTab(this.id)">Underline</td><td id="tab4" class="offtab" onClick="dhtml.cycleTab(this.id)">Show Date</td><td width="90%" class="tabpadding"> </td></tr>
</table>

Gdy tylko wczytamy dane konfiguracyjne z bazy danych, budujemy zakładki na samej górze formularza używając tabeli. Identyfikator 'id' każdej z komórek tabeli jest ustawiony jako ’tabX’, gdzie X odpowiada pozycji zakładki w tabeli, zaczynając od numeru 1. Mała pusta komórka na początku tabeli zapewnia, że zakładki nie ’zjadą’ na lewą stronę strony. Ostatnia komórka zapobiega rozciągnięciu się zakładek na cala długość strony. Aczkolwiek, jej szerokość jest ustawiona na 90%, rzadko kiedy będzie zajmować tyle miejsca.

<form action="index2.php" method="post" name="adminForm">
<div id="page1" class="pagetext">
<center>Bold: <?php echo mosHTML::yesnoSelectList( "bold", "", $row->bold ); ?></center>
</div>

Zaczynamy tworzenie formularza od dodania zawartości pierwszej zakładki. Używając analogicznego schematu nazewnictwa, jak powyżej, nadajemy zawartości każdej z zakładek nazwę pasującą do nazwy samej zakładki, czyli tab1 = page1, tab2 = page2 itd. To pozwala Javascript wykonanie całej funkcjonalności za nas, a my możemy się skoncentrować na wyglądzie.

<div id="page2" class="pagetext">
<center>Italic: <?php echo 
   mosHTML::yesnoSelectList( "italic", "", $row->italic ); ?></center>
</div>
 
<div id="page3" class="pagetext">
<center>Underline: <?php echo 
   mosHTML::yesnoSelectList( "underline", "", $row->underline ); ?></center>
</div>
 
<div id="page4" class="pagetext">
<center>Show Date: <?php echo 
   mosHTML::yesnoSelectList( "showdate", "", $row->showdate ); ?></center>
</div>

Następne fragmenty kodu są powtórzeniem poprzedniego wraz z odpowiednią zmianą nazewnictwa i wyświetlanych danych.

<input type="hidden" name="option" value="<?php echo $option; ?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="configid" value=<?php echo $row->configid ?> />
<input type="hidden" name="act" value="configure" />
</form>

Tutaj nic się nie zmienia, więc polecam lekturę oryginalnego kursu. Proszę zauważyć, że tutaj również zamykamy formularz (). Wynikiem, czego wszystkie nasze 4 elementy konfiguracyjne są na jednym formularzy ’adminForm’. To może być błogosławieństwo albo przekleństwo w zależności od efektu, jaki chcesz uzyskać. Jeśli chciałeś na każdej z zakładek uzyskać inny pasek narzędzi, odpowiedni do ustawień, to nie tędy droga. Problem polega na tym, że wszystkie skrypty w Mambo odnoszą się do formularza ’adminForm’ i do niczego innego. Jeślibyś próbował kilku wersji formularza ’adminForm’ na jednej stronie, Javascript ’zgłupieje’ i zawiesi się. Aczkolwiek, jeśli masz dużo opcji konfiguracyjnych przechowywanych w jednej tablicy i nie mieszczą Ci się na jednej stronie, zakładki mogą ułatwić Twoje życie.

<script language="javascript" type="text/javascript">dhtml.cycleTab('tab1');</script>
 
<?
}

To jeszcze nie koniec. Musimy powiadomić Mambo, którą zakładkę ma pokazać jako domyślną. Może się to wydawać niepotrzebne na pierwszy rzut oka, ale tak naprawdę daje nam to więcej elastyczności w projektowaniu zakładek. Powiedzmy, że z innych stron administracyjnych chciałbyś odesłać administratora do pewnej konkretnej grupy ustawień. Możesz przesłać zmienną i wprowadzając tutaj odpowiednie warunki if() lub switch() wymusić wyświetlenie konkretnej zakładki.

Zmieniony ( 14.12.2007. )