Supporto volontario e collaborativo per Joomla!® in italiano

Personalizzare il componente content con gli override - Prima parte

Valutazione attuale: 5 / 5

Stella attivaStella attivaStella attivaStella attivaStella attiva
 
Codice
Ciao a tutti,
questo è il mio primo articolo di una serie, cercherò di mostrare come personalizzare il componente content! 
Prima di tutto ecco cosa andremo a fare:
Il nostro obiettivo è permettere all'utente di poter caricare i video presi direttamente da youtube nel pannello di amministrazione. Questi verranno mostrati tramite un plugin content direttamente nel sito. Noi ci concentreremo solo sulla parte di amministrazione, buona lettura!.
Piccola gif che mostra quello che andremo a realizzare.



Immagine: parte centrale che l'utente vede appena entra nella sezione apposita di amministrazione



Immagine: menu per accesso alla sezione




Immagine: seleziona un video 



Ok per ora abbiamo terminato con le immagini vediamo ora la lista della spesa!

- php - per la parte di joomla
- javascript / jQuery - per rendere più dinamico e automatico il tutto 
- css - per dare un pò lo stile
- un account youtube data api abilitato 

la prima implementazione (questo articolo ) sarà un pò grezza una prima bozza solo per far funzionare le cose 
in seguito implementeremo delle ottimizzazioni sia stilistiche (non è il mio forte) sia di struttura a livello di codice.

Da dove partiamo ? 
Abbiamo deciso cosa fare adesso dobbiamo capire come farlo.
Io non avevo mai fatto nulla di simile quindi mi sono armato di pazzienza ed ho googlato  ecco cosa ho trovato:


- https://docs.joomla.org/How_to_override_the_output_from_the_Joomla!_core
https://magazine.joomla.org/issues/item/721-Customizing-the-Admin-Menu
https://github.com/sparkbuilt/lendr
http://www.inmotionhosting.com/support/edu/joomla-3/create-component/helloworld
https://github.com/joomla/Joomla-3.2-Hello-World-Component
http://joomla.stackexchange.com/questions/3579/joomla-3-x-extension-development-tutorial-for-a-beginner-developer
https://docs.joomla.org/J3.x:Developing_an_MVC_Component

molti articoli servono per capire come costruire un componente da zero, il mio scopo non era questo ma mi serviva per capire come "personalizzare" il componente base tramite l'override. La prima cosa da fare in assoluto è farsi un backup del sito oppure come ho fatto io avere un sito per lo sviluppo ed un sito per la produzione.  

COPIA DEL TEMPLATE

Seguiamo questa guida è fatta molto bene nel mio caso il template si chiama isis ma potete usare il nome che volete. Nell'articolo voi dovete mettere al posto di 
NOME_MIO_TEMPLATE_COPIATO il nome del vostro template.

http://www.joomla.it/video-guide/8018-creare-una-copia-del-template-joomla-e-gli-override-dei-css.html 

in pratica rinominando il template in caso di aggiornamento di joomla (come dice bene il video) il vostro lavoro non andrà perso è un buona pratica da seguire sempre.

OVERRIDE DEL COMPONENTE.

Facciamo l'override del componente content. Vi mostro i passi da seguire.

Selezionare Templates 

 

Selezionare extension 


Selezionare il template usato per l'amministrazione 




Selezionare content per fare l'override



Bene a questo punto verrà mostrata una schermata in cui verrà indicato dove è stato fatto l'override del nostro componente. Tranquilli fra poco iniziamo a vedere un pò di codice.

Nella logica di Joomla abbiamo questo schema 

- Copia template isis
   - Override del componente content 
      -  Aggiunta layout alla vista Article 
         - Cioè copia file edit.php (layout) in editvideo.php

Questo è il file principale su cui andremo a lavorare, alcune parti di le modificheremo altre invece le aggiungeremo completamente.

MODIFICHE AL CODICE

Immagine: struttura cartelle dopo override, percroso admininistrator/template/ facciamo una copia del file edit.php è lo chiamiamo editvideo.php.



Apriamo il file appena creato ed iniziamo le modifiche al codice.

Per semplificare tutte le operazioni ho creato un gist su github con i file completi edit.php e editvideo.php

Questi sono i link dove potete visionarli.
https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-edit-php-original
https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-editvideo-php-custom

Nella prima parte del file troviamo del codice Javascript che dobbiamo modificare.
Inizia a questa riga: https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-edit-php-original-L64

JFactory::getDocument()->addScriptDeclaration('
	Joomla.submitbutton = function(task)
	{
		if (task == "article.cancel" || document.formvalidator.isValid(document.getElementById("item-form")))
		{
			jQuery("#permissions-sliders select").attr("disabled", "disabled");
			' . $this->form->getField('articletext')->save() . '
			Joomla.submitform(task, document.getElementById("item-form"));

			if (task !== "article.apply")
			{
				window.parent.jQuery("#articleEdit' . (int) $this->item->id . 'Modal").modal("hide");
			}
		}
	};
');


Noi dobbiamo semplicemente aggiungere un commento in questo punto  

//. $this->form->getField('articletext')->save() 

questo commento serve per evitare controlli a runtime sul campo articletext, nel mio caso specifico perchè il campo edit lo riempiremo automaticamente 
senza interazione con l'utente.

La seconda modifica al nostro file è più importante ecco il codice. Questa parte è tutta da aggiungere.

JFactory::getDocument()->addScriptDeclaration('

 jQuery(document).ready(function(){		
		jQuery(\'#jform_catid\').find(\'option:selected\').removeAttr(\'selected\');
		jQuery("select[name=\'jform[catid]\']").find("option[value=\'20\']").attr("selected",true); 

		jQuery.ajax({
			url: "https://www.googleapis.com/youtube/v3/search?part=snippet%2Cid&channelId=XXXX&maxResults=50&order=date&fields=items(id%2FvideoId%2Csnippet(thumbnails%2Fdefault%2Ctitle))&key=YYYY", 
			dataType: "jsonp",
			success: function(data){
					//console.log(data.items[0].snippet.title);  
					var $ul = jQuery("#list_of_video");
					jQuery.each(data.items, function(idx, item){
					var url = item.snippet.thumbnails.default.url;
					var currValue = "' . strip_tags($this->form->getValue('articletext'))  .'";
					var cssClass ="";
					if (currValue == item.id.videoId) {
						cssClass="selectVideo";
					}
					else {
						cssClass="";
					}
                	
					$ul.append("<div data-target=\'"+ item.snippet.title + "\' id=\'"+item.id.videoId+"\' style=\'height:80px;float:left;margin-bottom:1px;margin-right:8px;\' class=\'" + cssClass + " list-group-item list-group-item-info\' >" 
						+ "<img height=\'80\' width=\'80\' src=\'"+ url + "\' />"
						//+ item.snippet.title 
						+ "</div>");
            })         
			},
			error: function(jqXHR, textStatus, errorThrown) {
				//alert (textStatus, + " | " + errorThrown);
			}
		});
 });    
');

Vediamo ciascun pezzo di codice con calma

con jquery seleziono il blocco jform_catid (che contiene l'id della categoria selezionata) poi seleziono una option, infine tolgo la selezione predefinita.
jQuery(\'#jform_catid\').find(\'option:selected\').removeAttr(\'selected\');

seleziono il campo select del form poi cerco l'option con valore 20 (20 == id database mia categoria predefinita in questo caso video) e lo seleziono aggiungendo l'attributo selected.
jQuery("select[name=\'jform[catid]\']").find("option[value=\'20\']").attr("selected",true); 

Queste due righe di codice scritte sopra le ho messe per evitare all'utente di selezionare la categoria "video" in pratica (nel mio caso) ogni volta che salva automaticamente imposta questa categoria, nel vostro caso l'id potrebbe cambiare oppure se non vi serve questo automatismo potete semplicemente non mettere il codice.

La parte successiva è più corposa ma non è complicata la spiegherò passo passo. Prima di tutto usiamo jQuery per fare una chiamata Ajax al servizio di google
(riga url....), dopo tramite dentro success quando arrivano i dati li processiamo. 

jQuery.ajax({
			url: "https://www.googleapis.com/youtube/v3/search?part=snippet%2Cid&channelId=XXXX&maxResults=50&order=date&fields=items(id%2FvideoId%2Csnippet(thumbnails%2Fdefault%2Ctitle))&key=YYYY", 
			dataType: "jsonp",
			success: function(data){
					//console.log(data.items[0].snippet.title);  
					var $ul = jQuery("#list_of_video");
					jQuery.each(data.items, function(idx, item){
					var url = item.snippet.thumbnails.default.url;
					var currValue = "' . strip_tags($this->form->getValue('articletext'))  .'";
					var cssClass ="";
					if (currValue == item.id.videoId) {
						cssClass="selectVideo";
					}
					else {
						cssClass="";
					}
                	
					$ul.append("<div data-target=\'"+ item.snippet.title + "\' id=\'"+item.id.videoId+"\' style=\'height:80px;float:left;margin-bottom:1px;margin-right:8px;\' class=\'" + cssClass + " list-group-item list-group-item-info\' >" 
						+ "<img height=\'80\' width=\'80\' src=\'"+ url + "\' />"
						//+ item.snippet.title 
						+ "</div>");
            })         
			},
			error: function(jqXHR, textStatus, errorThrown) {
				//alert (textStatus, + " | " + errorThrown);
			}
		});

Questo blocco di codice, estrae dal form il valore attuale dentro articletext e dopo averlo "ripulito" lo confronta con il videoId ottenuto dalla chiamata Ajax, infine se il videoId è uguale imposta una classe css che aggiungerà al rettangolo del video un trattino verde (selezionato).

var currValue = "' . strip_tags($this->form->getValue('articletext'))  .'";
					var cssClass ="";
					if (currValue == item.id.videoId) {
						cssClass="selectVideo";
					}
					else {
						cssClass="";
					}​

Serve nel caso d'uso in cui l'utente riapre un video precedentemente salvato (attualmente non è utilizzato ma nei prossimi articoli servirà).

Per quanto riguarda il servizio google vi rimando alla doc ufficiale eventualmente chiedete nei commenti.
https://developers.google.com/youtube/v3/
https://developers.google.com/youtube/v3/docs/search/list#try-it

Quando facciamo la chiamata dobbiamo mettere al posto di XXXX il canale youtube e al posto di YYYY
la chiave dell'utente usato per fare la richiesta il tutto è configurabile tramite link indicati sopra.

I risultati della chiamata Ajax avranno un aspetto simile 

{
 "items": [
  {
   "id": {
    "videoId": "rnFaDXD8GAE"
   },
   "snippet": {
    "title": "Nicolino Nicolino Garau Febbraio 2016 b",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/rnFaDXD8GAE/default.jpg",
      "width": 120,
      "height": 90
     }
    }
   }
  },
  {
   "id": {
    "videoId": "kIZ7dD4U2iI"
   },
   "snippet": {
    "title": "Nicolino Garau Febbraio 2016",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/kIZ7dD4U2iI/default.jpg",
      "width": 120,
      "height": 90
     }
    }
   }
  },
  {
   "id": {
    "videoId": "_6yM6-2aTaQ"
   },
   "snippet": {
    "title": "Maggio 2015",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/_6yM6-2aTaQ/default.jpg",
      "width": 120,
      "height": 90
     }
    }
   }
  },
  ...
  

quello che dobbiamo fare è processare questi dati e rappresentarli in html in pratica lo facciamo in questo loop ( each in jQuery) 

jQuery.each(data.items, function(idx, item){
					var url = item.snippet.thumbnails.default.url;
					var currValue = "' . strip_tags($this->form->getValue('articletext'))  .'";
					var cssClass ="";
					if (currValue == item.id.videoId) {
						cssClass="selectVideo";
					}
					else {
						cssClass="";
					}
                	
					$ul.append("<div data-target=\'"+ item.snippet.title + "\' id=\'"+item.id.videoId+"\' style=\'height:80px;float:left;margin-bottom:1px;margin-right:8px;\' class=\'" + cssClass + " list-group-item list-group-item-info\' >" 
						+ "<img height=\'80\' width=\'80\' src=\'"+ url + "\' />"
						//+ item.snippet.title 
						+ "</div>");
            }) 

Adesso dobbiamo gestire il click dell'utente su un video aggiungiamo questo blocco di codice 

JFactory::getDocument()->addScriptDeclaration('
	jQuery(function() {
		
		
		jQuery(\'#list_of_video\').on(\'click\', \'div\', function() {

			jQuery(\'#list_of_video div\').removeClass(\'selectVideo\');
			jQuery(this).addClass(\'selectVideo\');	
			
			var data = jQuery(this).attr(\'data-target\');
			jQuery(\'#jform_title\').val(data);
			jQuery(\'#jform_alias\').val(\'\');
			//{youtube}QJIVbnqk7SE|600|450|0{/youtube}
			jQuery(\'#jform_articletext\').html(\'{youtube}\'+ this.id + \'|600|450|0{/youtube}\');
    	});
	});

');

Quello che facciamo qui è gestire il click sul DIV dove è presente un video:

1.  rimuovo tutte le classi css selectVideo
2.  aggiungo la classe selectVideo al div cliccato
3.  recupero il titolo del video (data-target) e lo carico nel titolo
4.  svuoto l'alias
5.  riempo il campo testo di dettaglio con una stringa tipo {youtube} idvideo  |600|450|0{/youtube}

questo è molto dipendente dalla mia implementazione perché uso un plugin-content e come inserisco questa stringa nel campo articletext automaticamente mostra nel sito  il video youtube.

Aggiungo un titolo per la pagina
<h1> > Gestione inserimento video </h1>

Aggiungo il markup per contenere l'elenco dei video (il codice jquery di sopra usa questo markup). Sostituisco la gestione attuale del campo testo articolo e metto un textarea ma non visibile. Dal file editvideo.php tutta questa parte di codice la tolgo 

<div class="row-fluid">
			<div class="span9">
				<fieldset class="adminform">
					<?php echo $this->form->getInput('articletext'); ?>
				</fieldset>
			</div>
			<div class="span3">
				<?php echo JLayoutHelper::render('joomla.edit.global', $this); ?>
			</div>
		</div>
E la faccio diventare cosi
<div class="row-fluid">

			<div class="span12" >
			    <h2>Elenco video (Clicca su un video per caricarlo) </h2>
				<div  id="block_list_of_video" style="width:100%;overflow:scroll">
					<ul class="list-group" id="list_of_video">
					</ul>
				</div>
			</div>
			
			
			<div class="span9" style="margin-top:40px;">
				<fieldset class="adminform">
					<?php
					
					//echo $this->form->getInput('articletext'); 
						// print_r($this->form->getInput('articletext'));
						// die('stop');
					?>
					<textarea
						name="jform[articletext]"
						id="jform_articletext"
						cols=""
						rows=""
						style="visibility: hidden; width: 100%; height: 500px;"
						class="mce_editable"></textarea>
				</fieldset>
			</div>
			<div class="span3">
				<?php echo JLayoutHelper::render('joomla.edit.global', $this); ?>
			</div>
		</div>

Poi alla riga: https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-editvideo-php-custom-L195
aggiungo
		$params->show_urls_images_backend = 0;

Alla riga: https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-editvideo-php-custom-L215
aggiungo
		<?php $this->show_options = 0; ?>

Alla riga: https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-editvideo-php-custom-L220
aggiungo

		$params->show_publishing_options = 0;

A questo punto dobbiamo aggiungere una classe css al nostro template copiato la classe è questa 

/* custom */
.selectVideo {
 /*border-style: solid;
 border-color: red red red;
 border-width: 1px;*/
 background-color:lime;
}

Per aggiungere questa classe CSS  se avete seguito la guida in cima all'articolo non dovreste avere problemi

Dove solamente creare un file chiamato custom.css dentro la cartella css del vostro template precisamente
administrator/templates/NOME_MIO_TEMPLATE_COPIATO/css. Joomla farà tutto da solo e lo caricherà. 

L'ultima cosa che ci manca è la gestione dei menu in alto il codice è semplice eccolo
$menu->addChild(new JMenuNode("GESTIONE SITO", '#'), true);
	$menu->addChild(new JMenuNode("VIDEO", '#', 'class:install'),true);
	$menu->addChild(new JMenuNode("AGGIUNGI", 'index.php?option=com_content&view=article&layout=editvideo', 'class:install'));
	$menu->getParent();

e va inserito in questo file (dopo aver fatto l'override) administrator/templates/NOME_MIO_TEMPLATE_COPIATO/css/mod_menu/default_enabled.php
alla fine una riga sopra l'ultimo 

$menu->getParent();​

Ok queste sono tutte le modifiche che servono per ottenere quel risultato nei prossimi articoli faremo varie cose 

Ottimizzeremo il codice, miglioreremo le funzionalità, gestiremo il caricamento dell'articolo con l'auto selezione del video caricato (ora non è gestito questo), prepareremo una dashboard iniziale e tanto altro.

A questo link trovate il file finale con tutte le modifiche 
https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-editvideo-php-custom

Qua trovate il file per il menu 
https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c 
precisamente a questa riga
https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-default_eneable-php-custom-L399

Qua il custom.css
https://gist.github.com/BruceGitHub/1ed35b930dc44a7b85b81a48b4bd780c#file-custom-css


Per ora è tutto alla prossima grazie se avete gradito fatemelo sapere :-) 
good coding!!!



CommentaCommenta questo articolo sul forum

Ho scritto e condiviso questo articolo su Joomla.it, fallo anche tu. Invia ora un nuovo articolo!
roberto diana
Alcune informazioni su di me:
Lavoro nel campo della programmazione dal 2000... Adoro questo mondo e tutto quello che ci gira intorno :-)


Ho anche scritto:
         ✔ diventa autore su Joomla.it

Ultima versione di Joomla!®

downloadVer. 3.8.1 Stabile Italiana
Data di rilascio: 04 Ottobre 2017
(leggi la notizia Demo online

Le migliori estensioni gratuite

Un elenco aggiornato con i link a più di 100 estensioni fra componenti, moduli e plugin gratuiti per Joomla! 3

Manuale in italiano

Manuale in italianoPer conoscere meglio Joomla!, le sue caratteristiche ed il metodo di utilizzo leggi il manuale tradotto in italiano.

Molto utili anche le risposte alle domande più frequenti: FAQ

Sicurezza del proprio sito Joomla!Leggi anche: Nozioni sulla sicurezza del proprio sito

Autori di articoli recenti

Invia un articolo!Scrivi un articolo su Joomla.it e ricevi i ricavi dalle pubblicità di Google Adsense!
Segui queste istruzioni, condividi e collabora con la community. L'elenco degli autori attivi sul sito.

Libri consigliati

Torna su

Joomla.it sui Social Network

JoomlaDay Italia

JoomlaDay

Newsletter

Inserisci qui la tua e.mail: