Drupal 7 + Views 3 + Contextual filters

IngusNeilands Thu, 05/10/2012 - 17:28

Vai ir iespējams un kā var pievinot jaunu "Contextual filters" ?

Jau eksistē => Content: Created year + month (Date in the form of YYYYMM.)

Bet man vajag lai paths sanāk YYYY/MM

ps. Es te mēģinu uztaisīt wordpress-like post archive. Visi posti man ir pieejami sekojošā veidā:

blogs/ (all blogs)
blogs/YYYY/ (blogs by year)
blogs/YYYY/MM (blogs by month)
blogs/YYYY/MM/DD (blogs by day)
blogs/YYYY/MM/DD/title (specific entry)

:) Tas jau darbojas, izmantoju views :)

Palīdziet tikt galā ar arhīvu >?

Šo vakaru veltīju šīs problēmas pētīšanai, jo nesen arī man vienā projektā bija tāda pati situācija. Īsumā, diemžēl konkrētu risinājumu šai problēmai tomēr nevarēšu ieteikt, jo mana darba specifika nav saistīta ar PHP kodēšanu un moduļu izviedi. Taču šeit ir mazliet informācijas par iemesliem un iespējamiem risinājumiem. Var būt kāds no PHP speciem varēs Ingusam ko ieteikt. Iespējams, arī Ingus jau šo informāciju ir ieguvis. Koncepcija Lai panāktu šo risinājumu lietas ir vienkāršas. Ir nepieciešams skats, kurā tiek atlasīti un pēc vajadzības šķiroti noteikti satura veidi (Content type). Papildus šajā skatā ir jāpievieno 2 kontekstuālie filtri - attiecīgi YYYY un MM atsevišķi (Display all content), norādot Base path kā blogs (pēc piemēra) - tā teikt - vienkārši iespējojam. Page display šajā ziņā ir draugs, un manuāli viss darbojas (ievadot argumentus YYYY vai YYYY/MM formātā ar roku URL takā). Taču ar bloka izveidi ir "aizķeršanās". Šķietamie risinājumi Problēma ir izveidot šo bloku, kas palīdzētu ar vienu klikšķi nonākt pareizajā URL takā ar atbilstoši atlasītiem rakstiem, jo no zemāk apkopotā, tas īsti nedarbojas.
  • Bloks ar Contextual filter un Summary YYYY+MM
Itkā viss darbojas, taču nianse ir tajā, ka saites, ko šāds bloks dod automātiski, URL papildina ar nepareizo argumentu - YYYYMM, nevis, kā nepieciešams YYYY/MM. Kādēļ tas nav iekļauts un vis ticamāk arī netiks iekļauts Views (3) modulī ir aprakstīts šeit: http://drupal.org/node/293791 Tajā pat laikā šajā diskusijā ir piedāvāts labojums, kuru gan neesmu testējis. Pamata iemesls ir tas, ka Drupal "/" simbolu uzskata par argumentu atdalītāju, bet Summary risinājums piedāvā tikai viena argumenta piesaisti, kas standarta versijā ir YYYYMM (kopā). Arī vairāku argumentu (kontekstuālo filtru) saķēdēšana nedod rezultātus.
  • Manuāli veidots bloks un tā saites
Arī šim risinājumam ir nianses. Ir iespējas izveidot ar roku pareizo taku, taču papildus problēmas rodas rakstu skaita aprēķināšanā (jo nepieciešams papildināt bloku ar rakstu skaitu noteiktā laika periodā - optional, protams), kā arī ar Distinct Mēnesis, GGGG (x) ierakstu izveidi. Iemesls tam, ka šos unikālos ierakstus nevar izveidot ir saistīts ar to, ka Views uzstādījumi, kurus pieļauj UI tiek piemēroti pēc SQL meklējuma, bet Drupal datubāzē saglabā Unix Timestamp formātu. Līdz ar ko, ja 2011.gada maijā ir 2 raksti dažādās dienās, tad parādīsies divas saites uz Maijs, 2011 (1). Tas tādēļ, ka grupēšana tiek veikta ņemot vērā arī laika daļu raksta datumā (jeb timestamp), un tie vienādi var būt tikai unikālas sakritības un veiklu pirkstu gadījumā, jeb drīzāk nekad. Iespējamie risinājumi Drupal.org ir divi projekti, kas itkā šo lietu centās atrisināt:
  • WP Blog
    Taču te ir daudz var būt pat liekas funkcijas, un arī šis bloga rakstu atlases bloks nav īsti 1:1, ko Ingus vēlas, taču var būt to var izmantot.
  • Archive
    Arī papildina instalāciju ar liekām lietām, bet tomēr var būt ir izmantojams.
Divas alternatīvas metodes, kur būtu jāiesaista kodēšana, ir sekojošas:
  • Views bloka piedāvāto URL pārrakstīšana;
  • SQL pieprasījuma pārrakstīšana, lai timestamp laika porcija tiktu ignorēta, tādā veidā Views piedāvājot tīru datumu bez H:i:s (modulis vai PHP funkcija Views skatā)
URL pārrakstīšanu varētu veidot ar izstrādāta moduļa palīdzību, kur ieskats vai motivācija varētu būt rasta šeit: http://drupal.stackexchange.com/questions/29483/d7-views-3-blog-archive…. Alternatīvs risinājums ir izmantot tēmas template.php un template_preprocess_block() funkciju (http://api.drupal.org/api/drupal/modules!block!block.module/function/te…). Vai alternatīvi risinājumi (http://api.drupal.org/api/drupal/modules!block!block.api.php/function/h…). Es tiešām nebūšu kompetents sīkāk ko skaidrot šajos risinājumos, var būt kāds no PHP spečukiem varētu Ingusam ko precīzāk ieteikt. Nu un pēdējais risinājums (Kuru es aizgāju aktuālā brīdī) ir pieņemt to kā apstākli, kam nepieciešams nevis precīzs risinājums, bet vai nu izmantot to, kas ir, vai arī neizmantot vispār :) Ceru, ka kaut mazliet skaidrākas lietas ir par iemesliem, taču risinājumu nevaru pašlaik iedot. Kā Mearra puiši to būtu darījuši?
mēģini darīt tā ka skata ceļš ir "blogs",un tad likt klāt argumentus "Content: Created" - pirmais arguments gads, otrais mēnesis utt. un ja nav norādīta vērtība, tad izvēlēties argumenta opcijās "Show all". Netestēju, bet domāju ka tam vajadzētu darboties.
Nedarbojas tā. Jeb precīzāk, lai panāktu rezultātu, ka skata displejs atlasa rakstus pēc manuāli URL papildinātā argumenta - tur viss ir OK. Jautājums ir par Summary tipa bloka izveidi, kur klasiski tiek piedāvāts tikai viens arguments - YYYYMM, bet vajag, lai ir divi ar vienu klikšķi = YYYY/MM :) Tad nu meklēju iespēju, kā pārrakstīt URL jau esošam Views izveidotam Summary blokam. Biju domājis, ka to varētu kaut kā ar hook_preprocess_block() izdarīt, bet nezinu, kā tur aizķerties, jeb precīzāk, kā aizķert Views izveidotos linku ceļus, un vienkārši paņemt pēdējo argumentu, un sadalīt. Bet no PHP esmu tālu. Pagaidām tuvākais risinājums ir wp_blog moduli, bet arī ne gluži tā, jo tur ir grupējums pa gadiem, un pēc tam zem katra gada pa mēnešiem, bet vajag, lai ir Mēnesis, GGGG (x), kas ar vienu klikšķi novirza uz pareizu url ar 2 argumentiem - YYYY/MM.
1. lai blokā (sidebar) funkcionalitāte un izskats būtu tā, kā piedāvā Views Archive bloks - liste ar tekstu Janvāris, 2011 (2) 2. lai klikšķinot uz šo saiti atvērtos nevis piedāvātais 201101 arguments, bet gan 2011/01 - jeb divi argumenti. Views komplektā nākošais arhīva bloks piedāvā tikai Summary veidu, kuru uzstādi caur Contextual filter, un tikai vienu argumentu, bet Ingus vēlas, lai būtu korekts URL, piemēram, blogs/2011/01, neivs blogs/201101 Ar pašu attēlojuma un rakstu listes skatu nav problēmu. Jautājums ir kā izveidot to bloku, caur kuru varētu tās listes vērt, saglabājot iepriekš noteiktu URL formātu. Un vēl, nepiemirst, ka būtu vēlams aktivizēt linku, ja ir izvēlēts noteikts arhīva periods.
ok, pēc tam kad Jānis piezvanīja, laikam sapratu. Ja es pareizi sapratu, tad risinājums ir šāds: function CUSTOM_MODULIS_preprocess_views_view_summary(&$vars) { foreach ($vars['rows'] as &$row) { $date = array(); $date[] = substr($row->created_year_month, 0, 4); if (strlen($row->created_year_month) > 4) $date[] = substr($row->created_year_month, 4, 2); if (strlen($row->created_year_month) > 6) $date[] = substr($row->created_year_month, 6, 2); $new_created_year_month = implode('/',$date); $row->url = url('archive/'.$new_created_year_month); } } kā jāveido custom moduļus cerams nav jāizskaidro. Vēl ir opcija likt kodu template.php un CUSTOM_MODULIS jānomaina uz MANA_TĒMA. Piezīme: to darīt tikai tad ja netiek izmantota jau gatava contrib tēma. Var arī paņemt summary sagatavi no sites/all/modules/views/theme/views-view-summary.tpl.php, ievietot savā tēmā un mainīt $row->url vērtību tajā, bet es dodu priekšroku mazāk templeitu failiem. (piezīme: noteikti nemainiet failu pa taisno iekš sites/all/modules/views/theme)
Paldies Jānim, un strādā labi!!! Izmantoju šo funkciju iekš template.php sub-tēmā (zem Omega) - tātad ar Omega contrib ir viss kārtībā. Viss darbojas, kā plānots. Ir arī papildinājumi:
  • dēļ tā, ka $row->url tiek veidots šajā funkcijā, šis risinājums neņem vērā Views UI ievadītos parametrus Konteksta filtra Base path lauciņā. Līdz ar ko visu, kas ir pirms YYYY parametra, ieskaitot arī /, ir jāapraksta šajā funkcijā. Taču, ja ir vēlme izmantot Views UI parametrus, tad pēdējā rindiņa izskatās šādi: ... $row->url = url($vars['options']['base_path'] . '/' . $new_created_year_month); ...
  • pašlaik ir jādodas savos darboas, bet pie šī risinājuma vēl aktuāls paliek jautājums par class="active" piemērošanu aktīvajām saitēm. Pašlaik esošais risinājuma piedāvājums šo klasi nepievieno, līdz ar ko izvēlētais arhīva periods vizuāli nav atšķirīgs.
Ja neviens nebūs papildinājis šo kodu, es vēlāk atgriezīšos un paskatīšos, ko var darīt lietas labā.
ātrais (kreisais) risinājums ir ar $_GET['q'] == 'archive/'.$new_created_year_month nosacījumu likt klasi, bet tur noteikti ir kāds smalkāks risinājums ko bez apskatīšanās nepateikšu
Īsumā un ātrumā teikšu, ka ieviešot šo funkciju template.php, tiek atslēgta CSS klases pievienošana (kas ir iekš Views standarta risinājuma un strādā korekti), lai gan funkcija kā tāda modificē tikai $row->url. Es domāšanas virzienā pašlaik skatos uz iespēju modificēt visu linku, nevis tikai URL, kas attiecīgi dotu iespēju manuāli (caur tēmas template.php) klaisi pievienot, kā tas ir iekš views-view-summary.tpl.php. Taču pieslēdzot modifikācijas caur template.php tēmā, mainīgais $variables['row_classes'] pazūd un netiek ieviests.
Vis beidzot 'active' klase pie $row->url. Mazliet pamainīju arī savu iepriekš pausto viedokli par $vars['options']['base_path'] risinājumu. Ja gadījumā manā kodā ir nepilnības, lūdzu to piekoriģēt. Kodu izvietoju Omega apakštēmas template.php failā, kur par pamatu ir ņemts Jāņā Bebrīša rakstītais kods: http://www.drupal.lv/drupal-7-views-3-contextual-filters#comment-888 Taču jāsaka, ka man viss darbojas, ieskaitot arī base_path nomaiņu caur Views UI pie kontekstuālā filtra uzstādījumiem. Referencei un kodu daļām izmantots vēl šis resurss. function YOURTHEME_preprocess_views_view_summary(&$vars) { $view = $vars['view']; $argument = $view->argument[$view->build_info['summary_level']]; foreach ($vars['rows'] as $id => $row) { $date = array(); $date[] = substr($row->created_year_month, 0, 4); if (strlen($row->created_year_month) > 4) $date[] = substr($row->created_year_month, 4, 2); if (strlen($row->created_year_month) > 6) $date[] = substr($row->created_year_month, 6, 2); $new_created_year_month = implode('/',$date); $row->url = url($argument->options['summary_options']['base_path'] . '/' . $new_created_year_month); $active_urls = drupal_map_assoc(array( url($_GET['q'], array('alias' => TRUE)), // force system path url($_GET['q']), // could be an alias )); if (isset($active_urls[$vars['rows'][$id]->url])) { $vars['row_classes'][$id] = 'active'; } } }