CakePHP 3 – jak stworzyć bloga. Część 2. Elementy i edytor WYSIWYG

Niniejszy wpis jest kontynuacją części pierwszej. W tej części zajmiemy się dopracowywaniem naszego bloga. Wyposażymy zaplecze administracyjne artykułu w przycisk anuluj oraz edytor wysiwyg (ckeditor).Jeżeli masz uruchomiony serwer i otwartą stronę http://localhpst:8765/articles/add, możesz przejść do dalszej części. Jeżeli nie, to zrób to teraz, uruchamiając serwer wewnętrzny CakePHP poleceniem: bin\cake server i otwórz stronę.

Najpierw ciekawostka – proszę zestawić ze sobą pliki add.ctp i edit.ctp. z katalogu src/Templates/Article a potem z katalogu src/Templates/Categories. Prosze zauważyć, że niezależnie od modelu, różnią się one bardzo niewiele, zaś często jedyną różnicą jest wyłącznie nagłówek  <legend><?= __(‚Edycja artykułu’) ?></legend> lub  <legend><?= __(‚Dodawanie artykułu’) ?></legend>. Dodatkowo plik edit.ctp posiada może posiadać skrót usuwania bieżącego artykułu, który jest też dostępny w pliku index.ctp, więc przy edycji nie jest on konieczny.

Warto więc posłużyć się pewną prostą metodą, która sprawi, że zamiast konieczności modyfikacji dwóch plików add.ctp i edit.ctp, podczas zmian, będziemy musieli edytować wyłącznie jeden. Jak to działa? Wystarczy utworzyć jeden wspólny plik, który nazwiemy na przykład frm_article.ctp, w którym umieścimy formularz. Natomiast pliki add.ctp oraz edit.ctp będą się wyłącznie do niego odwoływać. Oczywiście jest to operacja opcjonalna i nie musisz jej przeprowadzać, ale w większych projektach, gdzie wykorzystuje się wiele pól baz danych, utrzymywanie jednego pliku  jest o wiele prostsze.

Oto jak tego dokonać:

  1. Utwórz plik frm_article.ctp w katalogu src/Templates/Element. Katalog element jest „widziany” przez inne widoki i może zawierać np. częściowe widoki, wstawiane w innych widokach poprzez funkcję $this->element(‚nazwapliku’);
  2. Skopiuj do nowo utworzonego pliku frm_article.ctp zawartość pliku add.ctp lub edit.ctp.
  3. Wykasuj zawartość plików add.ctp i edit.ctp i wstaw do każdego z nich tylko jeden wiersz: <?= $this->element(‚frm_article’) ?>

Zawartość pliku frm_article.ctp (skopiowałem do niego treść pliku edit.ctp):

<?php
/**
  * @var \App\View\AppView $this
  */
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
        <li class="heading"><?= __('Operacje') ?></li>
        <li><?= $this->Form->postLink(
                __('Usuń'),
                ['action' => 'delete', $article->id],
                ['confirm' => __('Czy na pewno chcesz usunąć {0}?', $article->title)]
            )
        ?></li>
        <li><?= $this->Html->link(__('List Articles'), ['action' => 'index']) ?></li>
        <li><?= $this->Html->link(__('List Categories'), ['controller' => 'Categories', 'action' => 'index']) ?></li>
        <li><?= $this->Html->link(__('New Category'), ['controller' => 'Categories', 'action' => 'add']) ?></li>
    </ul>
</nav>
<div class="articles form large-9 medium-8 columns content">
    <?= $this->Form->create($article) ?>
    <fieldset>
        <legend><?= __('Edycja artykułu') ?></legend>
        <?php
            echo $this->Form->control('title',['label'=>__('Tytuł artykułu')]);
            echo $this->Form->control('body',['label'=>__('Treść artykułu')]);
            echo $this->Form->control('category_id', ['label'=>__('Wybierz kategorię z listy'), 'options' => $categories, 'empty' => true]);
            //echo $this->Form->control('counter');
        ?>
    </fieldset>
    <?= $this->Form->button(__('Zapisz')) ?>
    <?= $this->Form->end() ?>
</div>

 

Zawartość pliku add.ctp i edit.ctp jest taka sama i jest następująca:

<?= $this->element('frm_article') ?>

To wszystko! Uruchom bloga i zwróć uwagę, że nie zmieniło się nic. System działa poprawnie, zaś my pozbyliśmy się konieczności utrzymywania dwóch plików. Jeżeli zajdzie dowolna zmiana w tabeli articles, wystarczy że zmienimy zawartość frm_article.ctp, zaś zamiana będzie dotyczyć zarówno operacji dodawania, jak i edycji artykułu. Oczywiście musimy nieco zaktualizować szablon frm_article.ctp, np. w najprostszy sposób usuwając linię <legend><?= __(‚Edycja artykułu’) ?></legend>.



Teraz nieco zmodyfikujemy treść pliku szablonu frm_article.ctp. Usuniemy z niego nagłówek i wprowadzimy przycisk anuluj. Proszę przyjrzeć się zmodyfikowanemu plikowi poniżej:

<div class="articles form large-12 medium-8 columns content">
  <?= $this->Form->create($article) ?>
  <fieldset>
    <legend><?= __('Artykuł') ?></legend>
    <?php
      echo $this->Form->control('title',['label'=>__('Tytuł artykułu')]);
      echo $this->Form->control('body',['label'=>__('Treść artykułu')]);
      echo $this->Form->control('category_id', ['label'=>__('Wybierz kategorię z listy'), 'options' => $categories, 'empty' => true]);
     ?>
   </fieldset>
<?= $this->Html->link(__('Anuluj'), ['action' => 'index'],['type'=>'button','class'=>'button']) ?>
<?= $this->Form->button(__('Zapisz')) ?>
<?= $this->Form->end() ?>
</div>

 

A oto efekt końcowy. Jeśli formularz nie wyświetlił się na całej stronie, sprawdź, czy zmieniłeś w elemencie div wpis large-12 (poprzednio było large-9):

Jak widać, pojawił się także przycisk Anuluj, który anuluje wpisywanie, bądź edycję artykułu. W rzeczywistości wykorzystałem tutaj link, lecz dopisując mu ‚type’=>’button’ zmieniłem link na przycisk, a dodatkowo poprzez zastosowanie klasy button, ma on dodatkowo ładną otoczkę. Tak samo będzie wyglądać edycja, bowiem przypominam, że pracujemy na wspólnym szablonie frm_article.ctp.

Teraz zajmiemy się edytorem wizualnym w polu treść

W tym celu wykorzystamy darmowy ckeditor. Edytor ten można pobrać ze strony twórców, ale jest on też dostępny wraz z przygotowaną przeze mnie konfiguracją jako załącznik do tego wpisu i waśnie tę metodę polecam.

Plik należy pobrać i po rozpakowaniu umieścić w folderze webroot\js\ckeditor. Teraz należy nieco zmodyfikować pliki add.ctp oraz edit.ctp w katalogu src\Template\Articles (jeśli nie utworzyłeś wspólnego szablonu) lub jeśli utworzyłeś jeden plik frm_article.ctp, zmiany wykonaj wyłącznie w tym pliku.

Należy dodać na początku pliku frm_article.ctp (lub add.ctp i edit.ctp) następujące linie:

<script>
    jQuery(function($){
        $('#tresc').ckeditor();
    })
</script>

<?= $this->Html->script('ckeditor/ckeditor') ?>
<?= $this->Html->script('ckeditor/adapters/jquery.js') ?>

Należy także zmienić nieco kontrolkę wyświetlającą zawartość pola body (typ w tabeli: TEXT), definiując jego identyfikator jako tresc:

echo $this->Form->control('body',['id'=>'tresc','label'=>__('Treść artykułu');

A oto cały kod źródłowy pliku frm_article.ctp:

<script>
    jQuery(function($){
        $('#tresc').ckeditor();
    })
</script>
 
<?= $this->Html->script('ckeditor/ckeditor') ?>
<?= $this->Html->script('ckeditor/adapters/jquery.js') ?>
<div class="articles form large-12 medium-8 columns content">
    <?= $this->Form->create($article) ?>
    <fieldset>
        <legend><?= __('Artykuł') ?></legend>
        <?php
            echo $this->Form->control('title',['label'=>__('Tytuł artykułu')]);
            echo $this->Form->control('body',['id'=>'tresc','label'=>__('Treść artykułu')]);
            echo $this->Form->control('category_id', ['label'=>__('Wybierz kategorię z listy'), 'options' => $categories, 'empty' => true]);
        ?>
    </fieldset>
<?= $this->Html->link(__('Anuluj'), ['action' => 'index'],['type'=>'button','class'=>'button']) ?>
    <?= $this->Form->button(__('Zapisz')) ?>
    <?= $this->Form->end() ?>
</div>

Gdy teraz odświeżysz stronę, tak naprawdę nic się nie stanie. Edytor nie zadziała, bowiem brakuje jeszcze jednego składnika, którym jest biblioteka JQuery. Na szczęście nie jest to duży problem, bowiem wystarczy dopisać tylko jedną linijkę kodu w głównym szablonie aplikacji.

Otwórz więc główny plik szablonu aplikacji, który znajduje się w katalogu src/Template/Layout i nazywa się default.ctp i dodaj wiersz w sekcji head:  <?= $this->Html->script(‚https://code.jquery.com/jquery-1.12.4.js’) ?>

<!DOCTYPE html>
<html>
<head>
    <?= $this->Html->charset() ?>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <?= $cakeDescription ?>:
        <?= $this->fetch('title') ?>
    </title>
    <?= $this->Html->meta('icon') ?>
 
    <?= $this->Html->css('base.css') ?>
    <?= $this->Html->css('cake.css') ?>
 
    <?= $this->Html->script('https://code.jquery.com/jquery-1.12.4.js') ?>
 
    <?= $this->fetch('meta') ?>
    <?= $this->fetch('css') ?>
    <?= $this->fetch('script') ?>
</head>

Ponownie odśwież stronę, a tym razem zobaczysz piękny, wizualny edytor tekstu twojego bloga.

To już wszystko na dziś. Mam nadzieję, że udało mi się w prosty i przystępny sposób opisać kilka możliwości znakomitego, lecz nie docenionego – przynajmniej w Polsce frameworka CakePHP 3.

Pytanie, sugestie, zgłaszanie błędów: leszek.klich@gmail.com

Ciąg dalszy nastąpi…

 

6096total visits,1visits today

Tagi , , .Dodaj do zakładek Link.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

47 + = 52

This site uses Akismet to reduce spam. Learn how your comment data is processed.