Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: CMS - założenia wstępne
Forum PHP.pl > Forum > PHP > Object-oriented programming
elnino.pl
W ciągu kilku najbliższych dni rozpocznę prace nad nowym projektem - CMS. Ogólne założenia są następujące:
  • Otwartość kodu (licencja GNU/GPL lub podobna własna)
  • Obiektowość (> php 5)
  • Integracja z bazą danych dzięki PDO (> php 5.1)
  • Lekki silnik będący jedynie interfejsem do obsługi modułów
  • Przerzucenie maksymalnej ilości kodu do modułów
  • Obsługa wielojęzyczności poprzez moduł gettextowy (pliki *.mo)
  • Część prezentacyjna: system szablonów (najprawdopodobniej Smarty)

A teraz zasada działania modułów na przykładzie modułu "aktualności":
  • Moduł dostarcza 2 widoki: "lista newsów" oraz "news", a także model pobierający z bazy dane
  • Użytkownik tworzy nową gałąź serwisu (np. ROOT/aktualnosci) nadając jej widok "lista newsów"
  • Widok "lista newsów" pozwala na dodawanie sobie podstron (np. ROOT/aktualnosci/news1), które mogą korzystać jedynie z widoku "news"
  • Każdy widok jest powiązany z plikiem konkretnym plikiem szablonu
Nie bardzo wiem jak rozwiązać uniwersalność pliku szablonu - aby po dodaniu nowego modułu nie trzeba było nic w nim ruszać - aby sam zaaplikował styl użytkownika. Myślę, że spokojnie CSS sobie poradzi - czyli design byłby tworzony jedynie z pliku CSS i obrazków, pliki szablonów byłyby w pewnym sensie podpinane "na sztywno".

Co o tym myślicie?

Nie mam jeszcze zielonego pojęcia jak rozwiązać w taki projekcie obsługę wielu jezyków - tak, żeby można było tłumaczyć bezpośrednio w panelu biorąc pod uwagę to, że niektóre wyrażenia do przetłumaczenia będą w bazie danych, a niektóre już w szablonie.
Diwi
Coż, założenia co do wykorzystania technologii są dobre. Jednakże ja mam i będę miał troszeczke inną koncepcje CMS'a. W mojej koncepcji możemy w panelu administracyjnym tworzyć typy treści (np. newsy, artykuły, opisy produktów itp.). Każda treść zawiera indywidualne elementy takie jak np. Tytuł, Wstęp, Rozwinięcie, Autor dla artykułu lub np. Tytuł, Tekst wiadomości dla newsów. Do tego każda wiadomość posiada dwa podstawowe szablony:
- listing treści
- pokazanie szczegółów wybranej treści

template możemy przerabiać według własnej woli, tworzyć nowe templaty dla tej samej treści (odpowiednio je nazywając itp.)

Dzięki takiemu rozwiązaniu stworzenie newsów do strony to kwestia 10 minut. Czyli tworzymy sobie nowy rodzaj treści, dodajemy elementy takie jak: Tytuł, Treść, Autor, Kategoria (dodatkowo cms powinien posiadać możliwość zarządzania strukturą drzewiastą treści). Później ustawiamy jako strone główną stronę z listingiem newsów, i tyle biggrin.gif

Pozdrawiam
piczu
@elnino
ja zamierzam u siebie zrobic pliki z jezykiem do kazdego modulu, wszystkie jezyki beda w bazie, a kazdy wpis na strone bedzie mial okreslony jezyk. jeszcze tego nie wyprobowalem ale odrazu jak naprawie swoj PC biore sie do pracy.
Ludvik
CMS to dokładnie to, o czym napisał Diwi. W swoim projekcie ograniczyłeś się tylko do newsów, więc musiał byś popracować nad tym jeszcze trochę.

Piczu: Jak pliki, to ich miejsce jest raczej na dysku niż w bazie. W takich zastosowaniach jednak lepiej sprawdzają się pliki. Nie ma co obciążać bazy niepotrzebnie, skoro nic z tymi danymi nie zrobisz specjalnego. Zauważ, że edycja takich danych wymaga połączenia z bazą. Danych z bazy nie będziesz mógł edytować w notatniku smile.gif Zobacz klasę Bastiona, tam to jest sensownie napisane.
piczu
@Ludvik
chyba zle mnie zrozumiales, mam zamiar zastosowac pliki jezykowe dla modulow a kazda zawartosc (czyli newsy, arty itp.) bedzie oznaczona jezykiem w jakim jest napisana. Polaczenie plikow z baza smile.gif
Diwi
Polecam zapoznanie się z tym tematem: http://forum.php.pl/index.php?showtopic=36095&hl=

W ostateczności zdecydowałem się na przechowywanie każdego elementu w osobnej kolumnie bazy danych.

Pozdrawiam
elnino.pl
Dzięki za wypowiedzi.

@Ludvik: czy rozumiesz wyraz "przykładowo"?

Wracając do tematu. Koncepcja jest następująca:
Każdy rodzaj strony musi posiadać następujące pola: tytuł, datę powstania, autora, itp. - treść natomiast może być różna:
- dla newsa: wstęp i pełna treść
- dla produktu w sklepie: opis, cena, fotki, itp.
- itd.

Wszystkie pola "specjalne" w bazie byłyby zapisywane w jednej kolumnie - jako zserializowana tablica, do której w szablonie będziemy się odwoływać poprzez {$data.price}, itp. Walidacja byłaby jeszcze w panelu, przed zapisem do bazy.
Ludvik
Cytat
@Ludvik: czy rozumiesz wyraz "przykładowo"?

Dziwnie się składa, że odpowiedź jest twierdząca. Czasami zdarza się człowiekowi nie doczytać, szczególnie o tej porze.
Cytat
Każdy rodzaj strony musi posiadać następujące pola: tytuł, datę powstania, autora, itp. - treść natomiast może być różna:
- dla newsa: wstęp i pełna treść
- dla produktu w sklepie: opis, cena, fotki, itp.
- itd.

Wszystkie pola "specjalne" w bazie byłyby zapisywane w jednej kolumnie - jako zserializowana tablica

Będziesz miał problem z sortowaniem danych względem pól "specjalnych". Poczytaj temat, do którego adres podał ci Diwi.

Cytat
A teraz zasada działania modułów na przykładzie modułu "aktualności":
  • Moduł dostarcza 2 widoki: "lista newsów" oraz "news", a także model pobierający z bazy dane
  • Użytkownik tworzy nową gałąź serwisu (np. ROOT/aktualnosci) nadając jej widok "lista newsów"
  • Widok "lista newsów" pozwala na dodawanie sobie podstron (np. ROOT/aktualnosci/news1), które mogą korzystać jedynie z widoku "news"
  • Każdy widok jest powiązany z plikiem konkretnym plikiem szablon

Skoro już mówimy o przykładzie, to większość u Ciebie robi widok. Na przykład "pozwala na dodawanie sobie podstron". Przy pisaniu CMS, ciężko będzie bez wzorca MVC. Mimo wszystko podszedł bym do sprawy inaczej, przypisując elementom typy, a nie widoki. Sprawa by była prostsza - widoki by były wymienne, niezależne od siebie, a same elementy były by łatwe do jednoznacznego zidentyfikowania.
elnino.pl
Cytat(Ludvik @ 13.07.2006, 11:07 ) *
Będziesz miał problem z sortowaniem danych względem pól "specjalnych". Poczytaj temat, do którego adres podał ci Diwi.

Racja, rozwiązanie to miało inne plusy, ale już zniknęły...

Cytat(Ludvik @ 13.07.2006, 11:07 ) *
Skoro już mówimy o przykładzie, to większość u Ciebie robi widok. Na przykład "pozwala na dodawanie sobie podstron". Przy pisaniu CMS, ciężko będzie bez wzorca MVC. Mimo wszystko podszedł bym do sprawy inaczej, przypisując elementom typy, a nie widoki. Sprawa by była prostsza - widoki by były wymienne, niezależne od siebie, a same elementy były by łatwe do jednoznacznego zidentyfikowania.


Czyli tak:
2 rodzaje widoków - content + listing

Dodajemy newsa (wszystkie pola dla niego odpowienie) i wybieramy do niego widok (jeden z dostarczonych przez moduł oznaczonych jako content).

I tu sprawa jest prosta, ale co z listingiem? Dla struktury:
ROOT/news/tytuł_newsa1
ROOT/news/tytuł_newsa2
ROOT/news/tytuł_newsa3
wiadomo, że ROOT/news/ będzie listingiem.

Ale jeśli zechcę dodać na stronie głównej dodatkowo listing? Albo w menu dowolnej innej podstrony?

Chciałbym, żeby z poziomu szablonu można było wywoływać soć takiego:

{module_block module=news order=date limit=5 var=zmienna}

i do zmiennej $zmienna wywalana jest tablica 5 najnowszych newsów (ich dane listingowe). I teraz możemy sobie w szablonie dowolnie to wyświetlić - jako listing, lista punktowana, itp.

Zależy mi jednak, żeby ten blok był generowany dynamicznie, a jednocześnie żeby korzystał ze skryptu, który powołuje do życia aktualny plik szablonu - żeby nie tworzył nowego połączenia z bazą i zapytania tylko po to, żeby pobrać te dane - czy to wykonalne? Chodzi o to, żeby skrypt rozpoznał zanim wywoła szablon to, co będzie w nim potrzebne i przygotuje to. Chyba będzie trzeba dodać pliki konfiguracyjne dla każdego szablonu zawierające listę bloków...
Diwi
Moje przemyślenia były podobne do Twoich.

Cytat
Zależy mi jednak, żeby ten blok był generowany dynamicznie, a jednocześnie żeby korzystał ze skryptu, który powołuje do życia aktualny plik szablonu - żeby nie tworzył nowego połączenia z bazą i zapytania tylko po to, żeby pobrać te dane - czy to wykonalne? Chodzi o to, żeby skrypt rozpoznał zanim wywoła szablon to, co będzie w nim potrzebne i przygotuje to. Chyba będzie trzeba dodać pliki konfiguracyjne dla każdego szablonu zawierające listę bloków...


Troszeczke nie rozumiem. Może stwórz sobie parser do własnych tagów typu <call:action name="getNews" ilosc="5" assign="zmienna" order="dataDodania, DESC"> po znalezieniu czegoś takiego wywołujesz sobie konkretnją akcje poprzez ActionHandler i przypisujesz zmienne do szablonu. Chyba o to Ci chodziło tongue.gif

Pozdrawiam
elnino.pl
Cytat(Diwi @ 13.07.2006, 11:43 ) *
Moje przemyślenia były podobne do Twoich.
Troszeczke nie rozumiem. Może stwórz sobie parser do własnych tagów typu <call:action name="getNews" ilosc="5" assign="zmienna" order="dataDodania, DESC"> po znalezieniu czegoś takiego wywołujesz sobie konkretnją akcje poprzez ActionHandler i przypisujesz zmienne do szablonu. Chyba o to Ci chodziło tongue.gif

Pozdrawiam

Niby tak, ale w chili, gdy szablon jest już parsowany będzie po ptakach - przecież to ostatnia faza tworzenia strony. Chyba zrobię tak:

Każdy szablon ma plik właściwy i plik konfiguracyjny, np.:
m.shop.content.tpl
m.shop.content.cfg

I jeśli wyświetlając produkt sklepu będziemy chciali gdzieś w szablonie dorzucić 5 najnowszych newsów - plik konfiguracyjny będzie wyglądał następująco:
Kod
block1|module:news|params:sort=date&limit=5
block_inny|...

tylko zapisane XMLem

I teraz widok przygotowuje się do podpięcia szablonu sprawdzając najpierw plik konfiguracyjny. Jeśli znajdzie w nim bloki - wywołuje odpowiednie akcje przypisując zmiennym dane - w przykładzie zmiennej szablonowej {block1} przypisana zostanie tablica, o którą prosiliśmy.

Czy to ma sens?
Diwi
Cytat
Niby tak, ale w chili, gdy szablon jest już parsowany będzie po ptakach - przecież to ostatnia faza tworzenia strony. Chyba zrobię tak:


Nie nie nie, on będzie preParsowany przez twój preFilter który zajmie się wywoływaniem akcji i przygotowywaniem danych.

Pozdrawiam
Ludvik
Ja bym się skłaniał ku rozwiązaniu problemu jedną akcją - ListNews. Przed pobraniem newsów musi ona posiadać wszelkie informacje o kontekście, z których może wywnioskować z jakimi parametrami ma wybierać newsy. Czyli jeżeli przesyłasz klucz do posortowania metodą GET, wtedy akcja znajdzie go i na jego podstawie pobierze odpowiednie dane. Do widoku dotrze tylko lista newsów do wyświetlenia.

EDIT:
Cytat
Nie nie nie, on będzie preParsowany przez twój preFilter który zajmie się wywoływaniem akcji i przygotowywaniem danych.

To by strasznie uzależniło model od widoku. A tego chyba nie chcemy? smile.gif
Diwi
Cytat
To by strasznie uzależniło model od widoku. A tego chyba nie chcemy? smilingsmiley.gif


Nie wydaje mi się aby to było wielkim problemem biggrin.gif
Ludvik
Ja bym obstawał przy zachowaniu standardowego przepływu danych we wzorcu MVC, gdzie do widoku płyną dane tylko w jedną stronę. Poza tym wstępna parsacja szablonów to trochę marnowanie czasu moim zdaniem. W razie zmiany widoku marnujesz cały efekt pracy filtra wstępnego. Samo napisanie tego nie powinno być większym problemem.
elnino.pl
@Ludvik: A co jeśli na jednej stronie chcę umieścić 2 bloki wyświetlające newsy (jeden 5 najnowszych, drugi 10 najpopularniejszych)?

A jak jest to rozwiązane w popularnych systemach? Przecież 90% stron ma budowę content + menu, w którym znajdują się bloki najnowszych artykułów, itp.
piczu
@elnino
tworzysz dwa takie modele, a kontroler je wywoluje przy danej akcji. Gorzej bedzie gdy bede chcial wywolac dwie modele z roznych kontrolerow (modulow). Mozna jeszcze zrobic jeden taki model laczacy te dwa, ale wtedy by bylo powtorzenie tych modeli co nie powinno sie robic.
NuLL
Temat: Wirtualne klasy contentu winksmiley.jpg
Temat: zarzadzanie trescia czyli jak odroznic obiekty winksmiley.jpg

Troche o tym zostalo powiedziane. Ja sobie to zrobilem w dwoch tabelach. Items & Items_properities - mowi to chyba wszystko. Proste to bo proste. Wyciaganie itemow to proste jest jak drut - na jakims MySQL 5.x czy PG proste podzapytanie i po bólu winksmiley.jpg Hardcore zaczyna sie podczas przesuwanie obiektow wraz z ich dzieciakami. Definicje klas trzymalem w XML. I tu sie zaczyna hardcore do kwadratu biggrin.gif Moze bledem bylo trzymanie defow w XML-u ale na nic praktyczniejszego nie wpadlem. Trzeba sobie praktycznie SVN-a napisac dla tych klas sad.gif Upartym jestem programista ale sie poddalem. Kiedy sie zmienia nazwe pola trzeba robic nowa wersje, tak samo podczas dodania nowego pola. Edytor klas napisalem - calkiem ladny byl winksmiley.jpg ale przy wersjonowaniu juz odpadlem. Pomijam jezyki tresci, wersjonowanie obiektow - to chyba musialby mi ktos zlecic abym to napisal bo nie wiem ile to mega kodu musi byc winksmiley.jpg

Jak ktos ma jakies dokladniejsze pytanie to postaram sie pomoc smile.gif
slash12345
Tylko nie .mo , takie rozszerzenie mają moduły SLAX-a.
elnino.pl
Wracając do tematu. Zastanawiam się jeszcze nad wyborem sposobu cache'ingu. Chciałbym, żeby skrypt był w miarę uniwersalny. Rozważmy przykład:
Gra online:
- treści podstron mogą być cache'owane, są w miarę statyczne
- w menu znajdują się natomiast boxy pochodzące z modułu gry, boxy te nie mogą być cache'owane

Korzystam z OPT. Nie bardzo wiem, w jaki sposób dodawać te boksy - musiałbym pre-parsować szablon, żeby sprawdzić, czy na danej podstronie znajduje się box, jeśli tak - wygenerować zapytanie do bazy i przekazać odpowiednie wartości do szablonu. Tak czy siak cała strona będzie odświeżana ("wykonywana ponownie") - nawet część, ktora jest statyczna. Chciałbym, aby w szablonie można było zrobić w szablonie tak:
Kod
{box module=nazwa_modulu type=typ_boxu params=cokolwiek cache=0}

I teraz w zależności od parametru "cache" box jest "liczony". Cała pozostała część strony jest pobierana z cache'u. Dodatkowym minusem jest to, że chciałbym, aby to wszystko korzystało z jednego połączenia z bazą, więc dane boxa musiałyby być przetwarzane przez skrypt wywołujący szablon. Jak mogę to rozwiązać (nie koniecznie w OPT)?
NuLL
Ja jakiegos czasu rozwiazalem to chamsko przez JSa ale to kazano mi tak zrobic rolleyes.gif

Innej metody niestety nie ma - szablon tak czy musisz przepuscic przez php aby sprawdzic wywolania boksu ( chyba ze JS guitar.gif )

Pozdr
elnino.pl
A własne znaczniki? Czy któryś z dostępnych systemów szablonów pozwala na tworzenie własnych znaczników i cache'owanie ich lub nie? Może znacie jakiś plugin?
sf
Cytat(elnino.pl @ 21.07.2006, 20:03 ) *
A własne znaczniki? Czy któryś z dostępnych systemów szablonów pozwala na tworzenie własnych znaczników i cache'owanie ich lub nie? Może znacie jakiś plugin?


A który znany system szablonów tego nie ma? tiredsmiley.gif
elnino.pl
Chodzi mi o wyłączenie tych bloków z cache'owania. Np. mam główną część strony (w miarę statyczną) pobieraną z bazy i boxy w menu, które muszą być za każdym razem pobierane.

Teraz w OPT sprawdzam, czy istnieje cache podstrony i jeśli tak, nie pobieram głównej części z bazy. Niestety używając znacznika "dynamic" dla jakiegoś elementu szablonu (znacznik nie cache'uje tego, co jest pomiędzy nim) funkcja isCached zawsze zwraca false i główna część strony i tak jest pobierana z bazy.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.