Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Klasa szablonu - czy się nada?
Evinek
post 11.07.2012, 20:05:52
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 11.07.2012, 21:24:30
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 12.07.2012, 09:33:44
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 12.07.2012, 20:10:20
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 12.07.2012, 23:21:17
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 14.07.2012, 14:48:59
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 14.07.2012, 17:57:05
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 15.07.2012, 14:21:07
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 15.07.2012, 19:50:14
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 16.07.2012, 09:38:33
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 16.07.2012, 11:18:41
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ź. smile.gif
Go to the top of the page
+Quote Post
droslaw
post 16.07.2012, 14:00:12
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 16.07.2012, 18:58:56
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')? 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. 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 16.07.2012, 19:14:30
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 19.07.2012, 20:06:43
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 22.07.2012, 19:26:25
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
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 13.06.2025 - 05:20