Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Klasa szablonu - czy się nada?
Evinek
post
Post #1





Grupa: Zarejestrowani
Postów: 280
Pomógł: 46
Dołączył: 23.03.2010

Ostrzeżenie: (0%)
-----


Tworzę klasę do obsługi szablonów. Mógłbym dać ten temat do działu Oceny, ale nie warto chyba o taką rzecz.
Chciałbym się dowiedzieć czy mój kod jest: optymalny, napisany prawidłowo z zasadami OOP i czy się nadaje na strone. Dodatkowo możecie napisać czy dobre mam nazewnictwo klasy, funkcji, zmiennych.

Jest tam jedna funkcja (get_dir()) której będę najwyżej używał poza klasą, a wewnątrz używam zmiennej dir.
Jeszcze myślę nad tym aby dać private funkcji load() ponieważ jest ona używana tylko wewnątrz klasy.

Kod:
https://www.dropbox.com/sh/eddsygq5kwhv3ty/FRDwEvOfGJ
Live:
http://evinek.ugu.pl/template/

Z góry dziękuje.
Pozdrawiam, Paweł.
Go to the top of the page
+Quote Post
peter13135
post
Post #2





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

Ostrzeżenie: (0%)
-----


Jest optymalne, ale... to raczej nie jest system szablonów, bo nie robisz swojego "języka" tylko korzystasz z "wbudowanego systemu szablonów w php". Smarty, czy twig to całkiem inna bajka. Tzn, szablon jest kodem php, więc trudno nazwać to system szablonów
Przydała by się opcja dodawania także tablic zmiennych, tzn zamiast set_var, funkca set_vars, trochę by to skróciło kod.

Poza tym, nazewnictwo zmiennych przyjeło się trochę inne np. getCośtam() lubięPlackiZMarmoladą() itd.

Poza tym... do stron sie nada, ale smarty czy twig są dużo lepsze.
Go to the top of the page
+Quote Post
Mephistofeles
post
Post #3





Grupa: Zarejestrowani
Postów: 1 182
Pomógł: 115
Dołączył: 4.03.2009
Skąd: Myszków

Ostrzeżenie: (0%)
-----


  1. public function load($file){
  2. include ($this->dir.$file.'.php');
  3. $page = ob_get_contents();
  4. echo $page;

Jaki to ma sens? Nie potrzebujesz echo, include przecież też wyświetli efekt.

Dobry przykład takiego komponentu.
Ale i tak lepiej używać Twiga.
Go to the top of the page
+Quote Post
Evinek
post
Post #4





Grupa: Zarejestrowani
Postów: 280
Pomógł: 46
Dołączył: 23.03.2010

Ostrzeżenie: (0%)
-----


Na początek funkcja load(). Jakimś cudem potrzebowałem kiedyś tego sposobu bo coś miałem nie tak. Samo include działa prawidłowo i się ciesze. Dzięki!

Co do peter13135, to tak:
Funkcją set() mogę dodać zmienną, tablice jak i nawet object. Chciałem po prostu abym mógł swobodnie przesyłać dane między szablonem a całym skryptem.
Co do nazewnictwa to również się zgodzę. Często widziałem, że pisali z podłogą nazwy i jakoś mi też się to napisało tak. Oczywiście przepisze te nazwy na nowo.

I jeszcze co do gotowych systemów. Nie chce mi się uczyć ich języków, ani bawić się ich skryptami. Wolę pouczyć się i robić w czystym PHP.

Pomógł dla oby dwóch. Jeszcze jakieś rady?

Go to the top of the page
+Quote Post
Mephistofeles
post
Post #5





Grupa: Zarejestrowani
Postów: 1 182
Pomógł: 115
Dołączył: 4.03.2009
Skąd: Myszków

Ostrzeżenie: (0%)
-----


Tak. Brakuje funkcji takich jak escape (pisanie za każdym razem htmlspecialchars itp. jest mało przyjemne), obsługi helperów (np. do generowania absolutnych URLi), rozszerzania szablonów (dołączanie części z innych to nie to samo).
Go to the top of the page
+Quote Post
Evinek
post
Post #6





Grupa: Zarejestrowani
Postów: 280
Pomógł: 46
Dołączył: 23.03.2010

Ostrzeżenie: (0%)
-----


Escape dodam. Helpery te dodać jako zwykłe funkcje w klasie czy jak? Bo za bardzo nie znam się na nich. Może parę słów więcej o tym?
Co masz na myśli "rozszerzenia szablonów"?
Go to the top of the page
+Quote Post
Mephistofeles
post
Post #7





Grupa: Zarejestrowani
Postów: 1 182
Pomógł: 115
Dołączył: 4.03.2009
Skąd: Myszków

Ostrzeżenie: (0%)
-----


http://symfony.com/doc/current/book/templa...nce-and-layouts
Tu masz wytłumaczone na czym polega rozszerzanie i dziedziczenie szablonów i czym się różni od dołączania szablonu do innych.
A co do helperów to rób jak chcesz, możesz dodawać je jako funkcje, które można uruchomić z szablonu, możesz jako klasy i uruchamiać je jakoś pośrednio.
Chodzi tylko o to, żebyś w szablonie mógł zrobić np.:
escape($costam) zamiast htmlspecialchars(), url('/costam') zamiast wpisywać absolutną ścieżkę za każdym razem itd.
Go to the top of the page
+Quote Post
droslaw
post
Post #8





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

Ostrzeżenie: (0%)
-----


Do helperów możesz użyć metody __call. Pozwoli ona ładować helpery w razie potrzeby. Jeśli będziesz miał dużo helperów, to lepsze niż dodawanie ich jako metody klasy Template.
Go to the top of the page
+Quote Post
Evinek
post
Post #9





Grupa: Zarejestrowani
Postów: 280
Pomógł: 46
Dołączył: 23.03.2010

Ostrzeżenie: (0%)
-----


Nad helperami jeszcze pomyśle jak zrobić.

Co do dziedziczenia to, jeśli dobrze zrozumiałem, chodzi o to, że po prostu tworzę kod do innego szablonu (np. news.php) i tylko zamieniam dane w divie (id="content").
Przykład ze stronki:
  1. <!-- src/Acme/BlogBundle/Resources/views/Blog/index.html.php -->
  2. <?php $view->extend('::base.html.php') ?>
  3.  
  4. <?php $view['slots']->set('title', 'My cool blog posts') ?>
  5.  
  6. <?php $view['slots']->start('body') ?>
  7. <?php foreach ($blog_entries as $entry): ?>
  8. <h2><?php echo $entry->getTitle() ?></h2>
  9. <p><?php echo $entry->getBody() ?></p>
  10. <?php endforeach; ?>
  11. <?php $view['slots']->stop() ?>

Czyli block "body" będzie zawierał kod i dodam go tylko w szablonie sposobem:
  1. <?php $view['slots']->output('body') ?>

Trochę to dziwne dla mnie i pewnie nie zrozumiałem do końca. Może ktoś jeszcze bardziej to wytłumaczyć?

Pomógł oczywiście dla oby dwóch.

PS. Nie mam zaawansowanego słownictwa w angielskim więc na początek próbuje czytać trochę, a później z translatorem lecę.
Go to the top of the page
+Quote Post
droslaw
post
Post #10





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

Ostrzeżenie: (0%)
-----


Wyobraź sobie taką sytuację. Masz dwa szablony: layout i news. News rozszerza layout. W momencie kiedy wyświetlasz szablon news, pojawia się layout z tym, że treść wybranych bloków/slotów layout`a może być określona w szablonie news. Przez to możesz stworzyć jeden layout dla całego serwisu, a pewne jego fragmenty będą zmienne w zależności od tego, czy wyświetlasz np. wiadomości, czy kategorie.

To co tworzy translator też zwykle chyba trudno zrozumieć.
Czytać teksty w obcych językach pomaga StarDict. StarDict nie tłumaczy całych zdań, ale możesz skonfigurować tak, że będzie wyświetlał okienko z tłumaczeniem zaznaczonego słówka. Tłumaczenie możesz zapisać na dysku w formacie html. Kiedyś napisałem skrypt, który te tłumaczenia konwertuje do formatu Paukera (dobrze się sprawdza w nauce słówek) i mogłem uczyć się np. w autobusie. Oszczędziło mi to sporo czasu.
Go to the top of the page
+Quote Post
Evinek
post
Post #11





Grupa: Zarejestrowani
Postów: 280
Pomógł: 46
Dołączył: 23.03.2010

Ostrzeżenie: (0%)
-----


Czyli, jeśli dobrze rozumiem, to będę miał na przykład taki szablon(layout.php):
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title><?php echo $this->get('title'); ?></title>
  6. </head>
  7. <body>
  8. <div id="error">
  9. <?php $this->block_load('error'); ?>
  10. </div>
  11. <div id="main">
  12. <div id="header">
  13. <!-- KOD HEADER -->
  14. </div>
  15. <?php $this->block_load('success'); ?>
  16. <div id="content">
  17. <?php $this->block_load('content'); ?>
  18. </div>
  19.  
  20. <div id="footer">
  21. <!-- KOD FOOTER -->
  22. </div>
  23. </div>
  24.  
  25. </body>
  26. </html>


A w szablonie news.php:
  1. <?php $this->block_start('content'); ?>
  2. //Pętla z newsami czy coś
  3. <?php $this->block_stop('content'); ?>
  4. <?php $this->block_start('success'); ?>
  5. <div id="success"> POPRAWNIE WYŚWIETLONO NEWSY </div>
  6. <?php $this->block_stop('success'); ?>


Klasa oczywiście automatycznie doda layout.php do news.php.
Dobrze rozumiem?

Ja miałem taki pomysł, aby zrobić takie coś:
Każdy szablon (np. news.php, contact.php) był by osobnym plikiem, a w nich bym ładował tylko te dane które są potrzebne. Przykład(news.php):
  1. <?php echo $this->getDoctype(); ?>
  2. <html>
  3. <head>
  4. <?php echo $this->getMeta(); ?>
  5. <title><?php echo $this->get('title'); ?></title>
  6. </head>
  7. <body>
  8. <div id="main">
  9. <?php $this->load('header'); ?>
  10. <?php $this->load('success'); ?>
  11. <div id="content">
  12. <?php $this->load('jeszcze_cos'); ?>
  13. </div>
  14.  
  15. <div id="footer">
  16. <?php $this->load('footer'); ?>
  17. </div>
  18. </div>
  19. </body>
  20. </html>

Wtedy będę mógł dodać menu (akurat na mojej stronce jest tylko w zakładce newsy) tylko do jednego szablonu, a jak będę chciał to do wielu.
W każdym "bloku" pobierał bym tylko dane ($this->get('zmienna')) i tam obrabiał ładnie w HTML'a.

Czy to nie jest lepszy pomysł niż z tymi blockami? Chyba nawet podobny bo w divie (id content) i tak będę ładował "bloki"(wyświetlenie listy newsów, podgląd itp.).

Czekam na odpowiedź. (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
droslaw
post
Post #12





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

Ostrzeżenie: (0%)
-----


Co do dziedziczenia, dobrze rozumiesz. Musisz tylko w szablonie potomnym zaznaczyć, który szablon rozszerzasz np:
  1. <?php
  2. // news.html.php
  3. $this->extend('layout.html.php');

W kodzie, który podałeś zmieniłbym jeszcze system nazewnictwa metod na CamelCase np. blockStart zamiast block_start.

W Twoim pomyśle jest ta wada, że mimo przechowywania nagłówków, menu itp. w osobnych sablonach dublujesz kod. Jeśli chciałbyś zmienić położenie menu, musiałbyś edytować każdy szblon.
Go to the top of the page
+Quote Post
Evinek
post
Post #13





Grupa: Zarejestrowani
Postów: 280
Pomógł: 46
Dołączył: 23.03.2010

Ostrzeżenie: (0%)
-----


To jakim sposobem miał bym np. włączyć menu tylko dla news.php?
$this->on('menu')? (IMG:style_emoticons/default/haha.gif)
Nie no, a tak serio, to jak taki problem rozwiązać?
Dziś lub jutro stworzę jakiś kod i zobaczymy wtedy czy będzie git. (IMG:style_emoticons/default/smile.gif)
A te blockStart i stopStart zrobić na funkcjach ob_start() itp. jakoś? Nie wiem czy zadziała, że w funkcji start włączę, w stop wyłączę + dodam do zmiennej - później sprawdzę.
Go to the top of the page
+Quote Post
droslaw
post
Post #14





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

Ostrzeżenie: (0%)
-----


Jeśli menu chcesz dołączyć tylko z szablonem news, możesz zdefiniować jego treść w tym szablonie, dla reszty ten blok będzie pusty.
blockStart i blockStop to właśnie ob_start i ob_get_clean.

Edit:

Ciągle piszemy blockStart i blockStop, ale te metody powinny nazywać się startBlock i stopBlock.

Ten post edytował droslaw 17.07.2012, 16:37:20
Go to the top of the page
+Quote Post
Evinek
post
Post #15





Grupa: Zarejestrowani
Postów: 280
Pomógł: 46
Dołączył: 23.03.2010

Ostrzeżenie: (0%)
-----


Dobra, coś stworzyłem.
Kod: https://www.dropbox.com/sh/3udzl1row9oxhvc/mJ4GKAEFw5
Live: http://evinek.ugu.pl/template/

Czy teraz jest wszystko dobre aby robić na tym szablony? Oczywiście jakieś poprawki jeszcze będą. Myślę też nad funkcjami typu addMeta, addCss itp.
W template news.php muszę ładować główny szablon (index.php) na dole aby działały blocki - ale to chyba nie problem.
Jeszcze jakieś rady?
Go to the top of the page
+Quote Post
droslaw
post
Post #16





Grupa: Zarejestrowani
Postów: 98
Pomógł: 33
Dołączył: 10.05.2011
Skąd: Krak

Ostrzeżenie: (0%)
-----


Nazwę klasy pisze się z dużej litery.
U mnie konstruktor przyjmowałby jako parametr pełną ścieżkę do szablonu. Napisałbym jeszcze jakąś ładowarkę, która ładowałaby szablony z katalogów określonych w konfiguracji, zależnych od aktualnego kontrolera itp. (to już inna klasa).
Metoda setTitle nie jest potrzebna wystarczyłoby set('title', 'tytuł');
Dodałbym metodę extend. Oznaczałaby ona, że trzeba doładować szablon po zakończeniu przetwarzania głównego szablonu(np. news). To byłoby bardziej czytelne niż load().

Ten post edytował droslaw 22.07.2012, 19:27:47
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.08.2025 - 02:52