Jump to content
php.lv forumi
Sign in to follow this  
Maris-S

Kopējais skripts kontrolieirem.

Recommended Posts

Labdien!

 

Gribēju pakonsultēties par labākām pieejām, kā iekļaut kopējo skriptu dažādos kontrolieros? Kopējais skripts varētu izvadīt tādus datus kā dažādus menu, piemēram augšējo un sānu menu, valodas utt. Kā un kur pareizāk un ērtāk būtu iekļaut šo kopējo skriptu? Rakstīt katram kontrolierim, piemēram Controller::_init() metodē to visu būs kopēšana, vēl iespēja būtu iekļaut kādu common.php tai pašā Controller::init() metodē, piemēram:

class UserController extends controller {
    function _init() {
        require_once('path/to/common.php);
    }
    
    function ProfileAction() {
        .....
    }
}

 

Viss tas strādā, bet sanāk ne visai smuki pašā common.php failā, jo ārpus objekta parādās, piemēram:

$this->view->languages = $page->get_languages();
$this->view->main_menu = $page->get_menu();
 

 

Kādas būtu labākās pieejas, lai visu to savienotu kopā?

 

Paldies!

Share this post


Link to post
Share on other sites

Kad kodēju PHP, izmantoju tādu sistēmu, ka kontrolerim bija $parent parametrs, kurā norādīju parent kontroleri.
Tādā veidā konkrētais kontroleris bija atbildīgs tikai par konkrētu lietu, bet parent kontroleris par kopējo layoutu.
Ārī parent kontrolerim varēja būt parent kontroleris.
Tāpat pastāvēja iespēja sazināties ar top parent kontroleri, piemēram, ja kādam kontrolerim vajag specifisku js, tad:

$this->top()->addJS("js/myjs.js")

 

Šādā veidā top vai kād pa vidu kontroleris var atbildēt par menu attēlošanu un tad attiecīgi no kontrolera var kontrolēt vajadzīgās lietas.

$this->top()->addMenu(array("MyMenyItem"=>"/linktomypage"))
$this->top()->setActiveMenuItem("MyMenuItem")

Otrs veids, kurš man ne pārāk patīk, jo nav loģisks, bet bieži ir novērots, ir tāds, ka templeits var izsaukt kaut kādu kopēju templeitu.
 

Share this post


Link to post
Share on other sites

Es gan, tieši pretēji, esmu par to, ka templeits veic šo uzdevumu un manto pats citu templeitu.

Share this post


Link to post
Share on other sites

{% extends "base.html" %}

{% load_js "custom.js" %}

{% include "block/foo.html" %}

Hello, world!

Share this post


Link to post
Share on other sites

Es gan, tieši pretēji, esmu par to, ka templeits veic šo uzdevumu un manto pats citu templeitu.

Teiksim, tev ir templeits all posts, kurš uzrenderē sarakstu ar postiem. Pēc loģikas, viņš atbild tikai un vienīgi par to, lai uzrenderētu šo sarakstu un viņam nav jāzin, kāds viņam augšā/sānos būs menu, vai kādā kopējā layoutā viņš tik iekļauts - tā drīzak ir konkrētā actiona izvēle.

Vēl vairāk, ja tev šo templeitu vajag izmantot vairākos layoutos, tad tev principā ir jāveido vairāki templeiti ar vienu un to pasu, tikai, kur katrs inklūdo atšķirīgu kopējo layoutu.

Tāpat problēmas rodas, ja attiecīgajam actionam ir jāpadod parametrs kopējam layoutam (piemēram, kurš menu aktīvs vai lapas title). Šādā gadījumā šis parametrs ir no sākuma jāpadot templeitam, kurš tālāk to padod kopējam layoutam.

Share this post


Link to post
Share on other sites

Ir bloki un ir templieti, kurus manto. Kalendāra vidžets būtu bloks, bet «About» lapa būtu templeits.

 

Manā piemērā nedaudz augstāk ir kods, kad parāda darbību.

Share this post


Link to post
Share on other sites

daGrevis, bet kā tavā piemērā tiks realizēti šādi gadijumi:

 

1) Ir "About" lapa. Bet tev ir divi layouti (base1.html, base2.html), kuri ir principiāli atškirīgi (piem., desktop un mobile), bet kuros abos var iekļaut šo about lapu?

2) base.html templeita attēlošanai ir vajadzīgs veikt kādas darbības (kontrolerī vai modelī), piemēram, jāielādē authentificētais lietotājs, viņa lietotājvārds, avatars, vai, piemēram, kā šijā forumā, footerī jāparāda lapas ielādes laiks. Kur šis darbības tiks veiktas un kā rezultāti tiks iekļauti base.html templeitā?

Share this post


Link to post
Share on other sites

Paldies par atbildēm! daGrevis, te doma ir ne tikai par vizuālo attēlošanu, tie menu ir tikai piemēri. Būtībā vairāk iet runa par pašiem kontrolieriem un to darbību, tas kā viņi dabū datus, piemēram menu no datubāzes, vai arī ieraksta datubāzē, vai veic kādas vispār ar db nesaistītas darbības. Vēl varētu būt arī darbības kā rezultātam nevajadzētu attēloties skatā, tā uz ātro, kaut vai apmeklējuma counteris.

Share this post


Link to post
Share on other sites

Codez,

 

Par variantiem:

 

1) Lajauts būs viens un tas pats, jo lapa būs responsive. Tomēr, ja vajag, tad...

 

{% if mobile %}{% extends "layouts/mobile.html %}{% else %}{% extends "layouts/desktop.html %}{% endif %}

 

Lai tas nebūtu jāraksta visur, var uztaisīt templeit-tegu: `{% extend_layout %}`.

 

2) Te laikam nav nekāds baigais pārsteigums, ka runāju par Django freimvorku. Ir divi varianti: konteksta procesors, kas templeitam pados jau gatavus mainīgos. Tie pirms tam _ir izrēķināti_ Python/PHP kodā, tā kā nav problēmas izdomāt. Šis te derētu `request`, `user` utml. mainīgajiem. Otrs variants ir midlvēris, kura princips ir gaužām vienkāršs: kustom klase ar predefinētām metodēm, kuras izpildās pirms rekvesta, pēc responsa, pirms templeit-renderinga un pēc, ja neklūdos. Tad derētu piemēram mioddlvērim, kas nosaka valodu pēc IP un redirektē lietotāju uz citu linku.

 

Māri,

 

Es saprotu, bet vienkārši vēlos izskaidrot domu — neliekas, ka tam vajadzētu būt kontrolerī. Tāpēc, ka kontroleris atgriež kkādus datus un tālāk templeits pats izdomā, vai tas ir HTML, JSON vai XML Javas 3rd-party API.

 

Tā ir MVC core-doma, ka loģika ir sadalīta. Katrs dara savu lietu, lai, pavisam vienkārši, **nebūtu mess**.

Share this post


Link to post
Share on other sites

daGrevi, tieši tā. Runa iet tieši par to ko atgriež kontrolieris, tam ir jābūt kontrolierī, nevis kaut kur citur. Piemēram, datus, kas tiek iegūti no datubāzes un padoti tālāk skatam. Tur arī sanāk ka bieži dažādiem kontrolieriem ir kādi pilnīgi vienādi dati un darbības, piemēram kontrolieriem user, shop, news, utt., visiem ir jādabū no datubāzes kāda pilnīgi vienāda informācija. Piemēram, ir pieprasījums:

 

mana_lapa.lv/lv/news/show/ziņas-virsraksts

 

Te var redzēt ka tiks izsaukts NewsController::ShowAction() un jā, viennozīmīgi viņam ir jāizpilda sava darbība, jāatgriež ziņa "ziņas-virsraksts", bet tā pat izsauktajam kontrolierim ir jādabū no datubāzes papildus informācija: valodas, visi menu, visādi jaunākie produkti kaut kur sānā, vai akciju preces, ja tas ir veikals, vai vēl visāda informācija. Ar tādas informācijas attēlošanu protams nodarbojas skats, bet ar datu, kuri tiek iegūti caur modeli no datubāzes, nosūtīšanu uz skatu nodarbojas kontrolieris un šeit tiek izsaukts tieši NewsController.

 

Protams to varētu atrisināt ar HMVC mazliet savādāk, bet to es negribu izmantot, tur savi trūkumi ir arī.

Edited by Maris-S

Share this post


Link to post
Share on other sites

Vari pastāstīt trūkumus HMVC? Neesmu aizdomājies.

Share this post


Link to post
Share on other sites

Nu pirmais kas ienāk prātā ir jādomā par mainīgo nosaukumiem, lai tie nepārklātos. Bet es varētu šeit arī kļūdīties, neesmu pētījis kādas ir pieejas, lai to atrisinātu. Nu un arī pieradums. Pašreizējam projektiņam nav laika pētīt un pārtaisīt uz HMVC, bet nākotnē būs jāpaskatās. :)

Share this post


Link to post
Share on other sites

Ir divi varianti: konteksta procesors, kas templeitam pados jau gatavus mainīgos. Tie pirms tam _ir izrēķināti_ Python/PHP kodā, tā kā nav problēmas izdomāt. Šis te derētu `request`, `user` utml. mainīgajiem.

Tātad konteksta procesors ir jāsagatavo/jāizsauc pašā kontrolerī. Papildus tam, šim konteksta procesoram ir jābūt tam, kurš ir atbilstošs konkrētajām layoutam.

Un, ja jau kontrolerī tiek pateikts - rekur, izmantojam šito konteksta procesoru, tad tajā paša solī varētu pateikt - rekur, izmantojam šito kontroleri par parent kontroleri un konkrēta kontrolera templeitam jau būtu vienalga. Sanāk, lai divās vietās rakstītu (izmantot šo konteksta procesorus/ ekstendotu šo templeitu), ir jāraksta vienā (par parent kontroleri izvēlēties šo kontroleri).

 

Lai vēl labāk demonstrētu domu dziļāks piemērs. Ir laba, kur ir base layouts, saukšu viņu par base.tpl, kurš satur head taga definīcijas un headeri. Lapā, atkarībā no lietotāja dzimuma ir dažādi menu, to izvietojums utml. resketīvi tik lielā mērā, ka prasās katram savs templeits un ir 2 templeiti male.tpl un female.tpl (tas ir tikai kā piemērs, var vienkārsi pieņemt, ka ir nbepieciešami 2 templeiti, kur katra gadijumā attēlojamie dati ir atškirīgi). Un tālāk teiksim ir sākumlapa, kurā ir lietotāja dashboards - dashboard.tpl.

Manā gadījumā, visu struktūru izveidot ir vienkārši - ir base kontrolris, kurš ielādē user datus, attelo to headerī, ir menu kontroleris, kurš nosaka user dzimumu, izvēlas templeitu, aprēķina dzimumam specifiskos datus un kuram parent kontroleris norādīts base un ir dashboard kontroleri, kuram parent kontroleris ir menu, kurš ielāde un apstrādā dashboard datus un izsauc dashboard templeitu. Neviens no nepleitiem nekad nezin, kas tad ir viņa parents un savā skopā sanem tikai un vienīgi sev atbilstošus datus. Starp citu tas ir vēl vien trukums ekstendojot templeitu - nedrīkst pārklāties mainīgo nosaukumi.

Otrs variants ir midlvēris, kura princips ir gaužām vienkāršs: kustom klase ar predefinētām metodēm, kuras izpildās pirms rekvesta, pēc responsa, pirms templeit-renderinga un pēc, ja neklūdos. Tad derētu piemēram mioddlvērim, kas nosaka valodu pēc IP un redirektē lietotāju uz citu linku.

Šis variants neder vispārigā gadījumā, kurā ir daudz variāciju, jo vienmēr darīs liekas lietas.

Share this post


Link to post
Share on other sites

Nu pirmais kas ienāk prātā ir jādomā par mainīgo nosaukumiem, lai tie nepārklātos.

Ko?

Share this post


Link to post
Share on other sites

Kavacky, paturpinot piemēru, pieņemsim ka mājas lapa kā tāda ir taisīta tā, lai labajā pusē vienmēr ir jaunākās ziņas, gan tad kad ir atvērta kāda preču sadaļa, gan tad kad atvērts lietotāja profils utt. Tagad tiek atvērta parastā sadaļa ar preču sarakstu un tiek izsaukts kontrolieris:

ShopController::SowProductsAction();

 

kas attēlo produktus, preču saraksts tiek nolasīts no datubāzes un piešķirts skata mainīgajam:

 

$this->view->item_list

 

Pašā skatā tas attēlojas, piemēram ar:

echo($this->item_list);

 

Tagad pieņemsim ka tiek izmantots HMVC un lai labajā pusē attēlotu jaunākās ziņas tiek izsaukts:

Common::ShowNews();

 

kas neko nezina par ShopController, iegūst jaunākās ziņas un piešķir savam skata mainīgajam:

 

$this->view->item_list

 

un ziņu skatā attēlo to mainīgo:

echo($this->item_list);

 

kas ir tāds pats kā preču sarakstam.

 

Kā jau teicu es iespējams kļūdos, jo neesmu pētījis kā īsti HMVC atrisina šo problēmu, iespējams ka tur ir savi risinājumu un iespējams ka tie ir labi risinājumi. To būs jāpapēta nākotnē.

 

Līdzīgas problēmas ir arī MVC, ja vienkārši kontrolierim _init() metodē iekļauj common.php, bet šajā gadījumā tas ir tikai viens fails un vienmēr sākumā, bet ja tiek izmantots HMVC, tad kontrolieri var tikt iekļauti viens otrā jebkādā secībā un jau nav tik vienkārši izsekot visam tam līdzi.

Edited by Maris-S

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...