Abbiamo qui a disposizione alcuni "tutorial" da altri chiamati anche "how to", che essenzialmente ci possono tornare utili per realizzare particolari sistemi, oppure semplicemente ci indicano come costruire qualcosa nel concreto, spesso sfruttando soluzioni e tecniche del tutto inusuali. Molto spesso queste quindi derivano dall'esperienza diretta di alcuni utenti che trovandosi di fronte ad un problema da risolvere o ad un obbiettivo da perseguire, hanno poi sviluppato l'idea sottoforma di guida sia per condividere i propri contributi sia per illustrare modalità "alternativa" per realizzare particolari funzionalità.
La sezione è in continua mutazione, quindi perdonateci se non è sempre aggiornatissima all'ultima guida. In caso di dubbi visitare la sezione "Documentazione" del forum e consultare la ToDo List e le Linee Guida per la documentazione.
Descrivo qua come ho affrontato il problema della registrazione sul portale che sto realizzando.
Si richiedeva potessero registrarsi due tipologie di utenti:
A seconda della scelta effettuata i campi da completare sarebbero risultati diversi. In particolare, con la seconda scelta, oltre ai campi per il profilo si doveva poter inserire sul portale l'azienda che l'utente rappresenta (e questa dovrà poi essere indicizzata per la ricerca).
L'utente (a qualunque profilo appartenga) doveva essere immediatamente loggato, visibile e con tutte le funzionalità; mentre l'eventuale azienda da questi inserita poteva essere visibile solo in seguito ad approvazione dalla redazione/amministrazione.
Sono stati dunque creati i seguenti ruoli per distinguere questi profili:
Moduli usati
I moduli utilizzati per raggiungere lo scopo sono stati:
Gestione utente > Permessi
e assegnare il permesso "cambia il suo nome utente" all'utente autenticato,token
per riempirlo automaticamente,Procedura
Passi da seguire:
Gestione utente > Impostazioni utente
e selezionare l'opzione "I visitatori possono creare profili e nessuna approvazione degli amministratori è richiesta". In questo modo l'utente può scegliersi direttamente la password in fase di registrazione e si trova loggato prima di dover rispondere all'email. D'altra parte potrebbe avere inserito una mail falsa o scorretta e per ovviare a questo problema si usa il modulo Login Toboggan. Sostituire anche l'email di \textit{Benvenuto} con:
!username,</li>
grazie per esserti registrato su !site.
Puoi ora effettuare l'accesso su !login_uri usando i seguenti nome utente e password:
nome utente: !mailto
password: !password
È importante che confermi la correttezza dell'email facendo clic su questo link:
!login_url
SE NON LA AUTENTICHERAI IL TUO UTENTE SARÀ CANCELLATA ENTRO UNA SETTIMANA!
-- Lo staff di !site
<strong>Pagina di registrazione (con scelta)</strong>
Scegli se vuoi registrarti come
<a href=user/register/profilepriv>PRIVATO</a>
oppure come
<a href=user/register/profileaz>AZIENDA</a>
registrazione
è un buon esempio, non lo è content/registrazione
). Questo per non creare conflitti successivamente con Auto Assign Role."edit own profile content"
. Inoltre, al momento della creazione profilo (quindi prima che l'utente sia autenticato) l'utente deve essere messo in condizione di poter modificare i campi del profilo e quindi i permessi di edit sui field del profilo vanno attribuiti anche agli utenti anonimi. Questa dunque è la parte più delicata; settare i permessi relativamente ai tipi di contenuto che dovranno gestire i vari ruoli.
Suggerimento:
Con il modulo Automatic Nodetitles si nasconde il campo titolo in una form.
Il campo titolo è quello usato anche nell'url di quel nodo.
Questo viene generato automaticamente a partire da un dato pattern.
In ogni tipo di contenuto si trova, dopo aver abilitato questo modulo, una sezione "Automatic title generation"
dove si può scegliere "Automatically generate the title and hide the title field".
Per scegliere come generarlo si può scorrere la lista dei token disponibili (http://drupal.org/node/390482).
Gestione Utente > Auto assign role > Assign from Path
in User Register Node
si inserisce la pagina che si vuole usare per sostituire la user/register
. Mettere qui il nodo di tipo Pagina creato al punto 4. Per ognuno dei ruoli che si intende usare spuntare "Attivato". Come metodo "Pages with no navigation" ed inserire path diversi a ruoli diversi (ad esempio user/register/profilepriv
e user/register/profileaz
)."(PreAutenticazione) user/register/profile"
dal tipo di contenuto Profilo Privato e "(Azienda) user/register/ecocompany"
dal tipo di contenuto Profilo Aziendale, ma anche dal tipo di contenuto Azienda.Costruzione del Sito > Temi > Configura > Impostazioni globali
c'è la voce Mostra le informazioni del contenuto su e lì si toglie la spunta da tutti i tipi di contenuto nei quali non voglio venga visualizzata la scritta "Inserito da ... il ...".Due moduli che potrebbero essere interessanti in questo contesto sono anche PageRoute e Real Name. Putroppo il primo non l'ho usato perché non sono riuscito a capire come integrarlo con quanto fatto, anzi non sono proprio riuscito a capire se sia compatibile con la fase di registrazione (lo era con Drupal 5 e il modulo Node Profile, ma sono portato a dire che da Drupal 6 Pageroute non sia utilizzabile in fase di registrazione). Real Name, invece, dovrebbe servire a sostituire, all'interno del portale, tutti i riferimenti all'utente con un field scelto dall'amministrazione (e quindi ad esempio un campo Nome_cognome
al posto del prefisso dell'email).
Trackback nella mia sezione nel blog i-ware.
In una delle mie installazioni di drupal ho subito un attacco da parte di alcuni spammer.
Si sono iscritti circa 5000 utenti spam e ognuno di essi ha creato approssimativamente un contenuto.
Mi sono mosso per capire come cancellare nel modo più veloce utenti e contenuti in modo tale che nelle pagine admin/content/node
e admin/user/user
i risultati fossero maggiori, così da risparmiare tempo (di default sono 50).
Il risultato della ricerca per risolvere il problema è stato questo metodo:
Versione di drupal usata 6.16
Per cancellare 200 utenti per volta invece che 50 modificare il file modules/user/user.admin.inc
andando alla funzione function user_admin_account()
sostituire:
$result = pager_query($sql, 50, 0, $query_count, $filter['args']);
con:
$result = pager_query($sql, 200, 0, $query_count, $filter['args']);
e poi, qualche riga più avanti nello stesso file, sostituire:
$form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
con:
$form['pager'] = array('#value' => theme('pager', NULL, 200, 0));
--------------------------------------------------------------
Per i contenuti modificare il file modules/node/node.admin.inc
andando alla funzione function node_admin_nodes()
sostituire:
$result = pager_query(db_rewrite_sql('SELECT n.*, u.name FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC'), 50, 0, NULL, $filter['args']);
con:
$result = pager_query(db_rewrite_sql('SELECT n.*, u.name FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC'), 200, 0, NULL, $filter['args']);
e poi, qualche riga più avanti nello stesso file, sostituire:
$form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
con:
$form['pager'] = array('#value' => theme('pager', NULL, 200, 0));
--------------------------------------------------------
Quando si visterà la casella -seleziona tutti- il browser prenderà più tempo (diversi secondi) per completare l'operazione.
Ovviamente l'uso del DB si intensifica. Tenerne conto in caso si abbiano dei limiti imposti da proprio hosting.
Non superare il 200 item per non affaticare il sistema
Problema: gli articoli creati/modificati dagli utenti devono essere approvati da un editor prima di essere pubblicati.
Come spesso accade Drupal permette di ottenere lo stesso risultato seguendo approcci e soluzioni diverse; in questo caso integriamo il modulo workflow con il sistema di revisione dei contenuti e le azioni di Drupal.
Soluzione:
l'autore crea o modifica un contenuto; può salvarlo come bozza (impostandone lo stato = bozza), oppure inviarlo per revisione (stato = revisione). il contenuto non viene pubblicato.
Quando lo stato di un contenuto è impostato come revisione, l'editor viene avvertito con una email e allo stesso tempo l'autore non ha più il permesso di modificarne il contenuto.
L'editor rivede il contenuto e se lo reputa idoneo, lo pubblica (stato = approvato), altrimenti lo rimanda per revisione all'autore (stato = bozza) ed il ciclo ricomincia. In entrambi i casi l'autore può essere avvertito con una email.
Il flusso di lavoro si può schematizzare più o meno così:
PASSAGGIO DI STATO AUTORE TRIGGER EDITOR
(permessi) (email) (permessi)
--------------------------------------------------------------
(creazione)->bozza X
bozza->revisione X "avverti editor"->
<-"avverti autore"
revisione->bozza <-"richiedi revisione" X
revisione->approvato <-"conferma autore" X
--------------------------------------------------------------
Supponiamo che si voglia applicare questo workflow al tipo di contenuto story:
A questo punto, quando il ruolo "autore" crea una story dovrebbe poter impostare lo stato di BOZZA o REVISIONE, mentre il ruolo "editor" ha in aggiunta una opzione APPROVATO
*) NOTA: in alcuni casi il placeholder %author non funziona, probabilmente perchè il modulo trigger viene chiamato troppo presto. La soluzione (non sempre) può essere di aumentare il peso (weight) del modulo trigger (ad esempio da "0" a "2") nella tabella {system} del database.
Un'altra possibilità è usare l'azione avanzata "send a tokenized email" fornita dai moduli token e token_actions:
- abilitare i moduli token e token_ actions (incluso in token)
- andare su admin/settings/actions
- nel form "Rendi disponibile una nuova azione avanzata", scegliere "Send tokenized e-mail"
- nel campo "Destinatario" della nuova azione creata, scrivere il token [author-mail]
- configurare e sostituire due azioni di questo tipo a quelle impostate per "richiedi revisione" e "avverti autore"
NOTA: questo workflow ha un limite importante: una volta che un contenuto è stato pubblicato gli autori non possono più modificarlo (o possono modificarlo live in base ai permessi). i moduli revisioning+module_grants possono essere aggiunti a questo workflow permettendo la modifica "in revisione" dei contenuti, ovvero l'autore può modificare un contenuto pubblicato ma solo creando una nuova revisione che verrà pubblicata (e sostituirà la vecchia versione) solo dopo l'approvazione dell'editor. Questi moduli permettono anche configurazioni molto più complesse di questa.
Alcuni altri moduli per la moderazione dei contenuti:
http://drupal.org/project/content_moderation
http://drupal.org/project/revision_moderation
http://drupal.org/project/modr8
http://drupal.org/project/publishcontent
http://drupal.org/project/comment_moderation
Bonus: http://drupal.org/project/diff
CiviCRM-Drupal in realtà non è altro che un grande modulo, addirittura più pesante della cartella di installazione di Drupal 6 (infatti il peso dell'archivio è di circa 7,5mb - scompattato arriva a 37mb circa...).
Una volta scompattato, esplorando il contenuto possiamo notare che, al suo interno, c'è una cartella chiamata "drupal" che a sua volta contiene (oltre a diversi file...) la cartella "modules".
La prima cosa che verrebbe in mente (almeno a me...) è che il contenuto di questa cartella "modules", debba essere copiato nel solito percorso dei moduli > sites/all/modules, invece non è così.
La cartella "modules" contiene i moduli di CiviCRM-Drupal e va lasciata così (si, anche lasciando la cartella Joomla! con tutto il resto...).
Il modulo CiviCRM-Drupal, oltre che essere un modulo, per comprenderlo meglio, lo si potrebbe definire come una sorta di CMS dentro la sezione Moduli, infatti, richiede un'istallazione proprio come si fa con drupal 6 (ovviamente l'interfaccia dell'installer è completamente diversa...)
1. Creare un nuovo database per ospitare CiviCRM-Drupal
2. Scaricare CiviCRM-Drupal da qui > http://sourceforge.net/projects/civicrm/files/
3. Scompattare l'archivio e copiare la cartella "civicrm" (lasciando tutto il suo contenuto così com'è...) in http://www.miosito.com/sites/all/modules/
4. Procedere con l'installazione > http://www.miosito.com/sites/all/modules/civicrm/install/
5. Nella schermata che ci appare ci saranno dei "warning" in rosso - Per risolverli:
- Inserire i dati relativi ai 2 database (Drupal 6 e CiviCRM-Drupal)
- Settare i permessi della cartella "default" (http://www.miosito.com/sites/default) a 777
6. Lanciare l'installer (che si trova nell'interfaccia) et Voilà... CiviCRM è installato!
7. Rimettiamo a posto i permessi della cartella "default" a 644 (nel mio caso, su dreamhost.com, i permessi si sono settati in sola lettura a 555 automaticamente...).
Adesso, accedendo nel nostro Drupal 6 avremo nel menu admin una voce in più: CiviCRM
Se vogliamo poi localizzarlo in più lingue dobbiamo scaricare il file "civicrm-3.1.4-l10n.tar" (L10n) che si trova tra gli archivi da dove abbiamo prelevato CiviCRM > http://sourceforge.net/projects/civicrm/files/
IMPORTANTE! - Il modulo nella sezione moduli di drupal.org > http://drupal.org/project/civicrm NON VA NE CONSIDERATO NE SCARICATO - Tutto quello che serve è nel download > http://sourceforge.net/projects/civicrm/files/
Infatti, c'è anche scritto bello maiuscolo e in grassetto > http://drupal.org/project/civicrm appena sopra il link del download e, sinceramente non ho ancora capito a cosa serve tale link...
Un ringraziamento particolare a Francesco Moretto - http://www.civicrm.eu/ - per la sua gentile disponibilità, cortesia e collaborazione...
Ciao
Kipper
Oggetto:Realizzazione di una lista di checkbox all'interno di un form ordinate su più colonne.
DESCRIZIONE:
Premetto che non è farina del mio sacco, la trovai in giro qualche mese fa, e l'autore se vedrà questo articolo mi perdonerà se non metto il link al suo sito (nn mi ricordo nemmeno dove l'ho trovato).
Molte volte mi sono trovato a dover gestire un checkbox con molte scelte e ad avere quindi una lunga lista di campi uno di seguito all'altro ottenendo un form lungo un chilometro.
Questo piccolo HOWTO genera un nuovo type per i checkboxes da inserire all'interno del proprio modulo.
HOWTO
1) Nel proprio file .module inserire la seguente funzione:
<?php
/**
* param array $element
* Elemento fapi da modificare.
*
* return array
* Elemento modificato.
*/
function _expand_checkbox_columns($element) {
$value = is_array($element['#value']) ? $element['#value'] : array();
$element['#type'] = 'checkboxes';
$element['#tree'] = TRUE;
if (count($element['#options']) > 0) {
if (!isset($element['#default_value']) || $element['#default_value'] == 0) {
$element['#default_value'] = array();
}
foreach ($element['#options'] as $key => $choice) {
$class = $column && ($column % $element['#columns']) ? 'checkbox-columns' : 'checkbox-columns-clear';
if (!isset($element[$key])) {
$element[$key] = array(
'#type' => 'checkbox',
'#processed' => TRUE,
'#title' => $choice,
'#default_value' => in_array($key, $value),
'#attributes' => $element['#attributes'],
'#prefix' => '<div class="' . $class . '">',
'#suffix' => '</div>',
);
}
$column++;
}
}
return $element;
}
/**
* Implementation of hook_elements().
*/
function nomemodulo_elements() {
$type['checkbox_columns'] = array(
'#input' => TRUE,
'#process' => array(
'_expand_checkbox_columns' => array(),
),
'#tree' => TRUE,
);
return $type;
}
?>
2) All'interno del form che si vuole generare potete utilizzare il type Checkbox_column come da esempio:
<?php
//....
$numero_colonne = 3;
$options = array(
'en'=>t('English (US)'),
'es'=>t('Español'),
'fr'=>t('Français'),
'it'=>t('Italiano'),
'ar'=>t('Arabic'),
'ur'=>t('Urdu'),
);
$results = db_query("SELECT lang FROM {newsletter_settings_lang};");
$i = 0;
$checked = array();
while( $data = db_fetch_object($results)) {
$checked[$i] = $data->lang;
$i++;
}
$form['lingua'] = array(
'#type' => 'checkbox_columns',
'#title' => t('Seleziona le lingue abilitate per le newsletter'),
'#columns' => $numero_colonne,
'#options' => $options,
'#suffix' => '<br style="clear:both;"/>',
'#default_value' => $checked
);
// ....
?>
Infine bisogna inserire il seguente css all'interno dei propri stili (ad esempio in style.css del proprio tema)
.checkbox-columns .form-item {
width: 15em;
margin-right: 10px;
float: left;
display: inline;
}
.checkbox-columns-clear .form-item {
width: 15em;
margin-right: 10px;
clear: left;
float: left;
display: inline;
}
Info generiche
Ironicamente potrei definire questa classe di tutorial con il nome "Drupal Module-Less" perchè nella pratica di tutti i giorni tento sempre di realizzare qualcosa in Drupal senza necessariamente utilizare un apposito modulo, ma cerco di raggiungere lo stesso obiettivo che mi sono prefissato con i moduli che ho già a disposizione o meglio ancora utilizzando i moduli cosiddetti "essenzliali".
In questo tutorial realizzerò un sistema di licenziamento dei contenuti (nodi) di Drupal in perfetto stile Flickr utilizzando Content Type, Cck Node Reference, Cck Link e Path Auto. Penso siano moduli semplici e che nella maggior parte dei casi possono essere definiti moduli senza dei quali non si fa quasi nulla in Drupal.
1. Creare un Content Type “Licenza”
Per prima cosa bisogna creare un nuovo tipo di nodo andando in “Administration > Content Type > Add Content Type”, per esempio lo chiamiamo "Licenza", impostiamo poi i campi che ci vengono chiesti come meglio crediamo, per il momento non sono essenziali.
2. Path Auto dà un tocco di stile
Per facilitarne eventualmente la comprensione e la navigazione all'interno del nostro sito possiamo, tramite Path auto, assegnare una path visibilmente più piacevole ed accessibile, per esempio assegnando al nostro Content Type di tipo "Licenza" la path "licenza/[title-raw]", il che è induce che tutti i nodi di tipo "Licenza" saranno raggiungibili dalla path http://miodomino.it/license/Titolo-Del-Nodo e senza dubbio dà un tocco di serietà e allo stesso tempo le differenzia dai nodi veri e prori del sito.
Quindi andiamo “Administration > URL aliases > Automated alias settings”, scorrendo la pagina troveremo il blocco probabilmente collasato che riguarda i nodi dal nome “Node path settings”.
Decollassandolo troveremo la riga inerente al Content Type “Licenza” indicato probabolmente con “Pattern for all Licenza paths:”, ineriamo quindi nel campo sottostante “licenza/[title-raw]" ed attiviamo “Bulk generate aliases for nodes ...” ed infine applichiamo le modifiche.
3. Aggiungiamo qualche Field utile
3.1 Content Type: Licenza
Nel nostro caso utilizzeremo il campo "Titolo" e "Body" che Drupal ci offre in modalità di default, inserendo nel "titolo" ad esempio il nome completo della licenza e nel "body" un riassunto esplicativo della licenza, non mi sembra il caso di inserire il testo completo o il legal code qui dentro.
Infatti quest'ultimi campi gli inseriremo con degli utili link a fondo del nodo tramite l'aggiunta di alcuni "Field" utili, per fare questo spostiamoci in “Home > Administer > Content management” e clicchiamo sulla voce “Manage Fields” in corripondenza del Content Type “Licenza”.
Aggiungiamo un “Field” di tipo “cck Link” e gli assegnamo il nome che preferiamo, ad ogno modo teniamo bene a mente che in questo campo saranno inseriti una serie di “link utili” a rendere comprensibile e valida giuridicamente il riassunto che abbiamo inserito nel campo “Body”.
Personalmente ho limitato il numero di “Fields” aggiuntivi ad uno solo, ma per esigenze stilistiche o di usabilità potreste adattare questa parte come meglio credete, per esempio si potrebbe suddividere il tutto inserendo compi come dal nome “Legal Code”, “Traduzione”, “Logo” ecc.
3.2 Gli altri Content Type
A questo punto non ci tocca che aggiungere la possiblità di “collegare” le licenze ai nodi che preferiamo, spostiamoci su “Home > Administer > Content management” e clicchiamo sulla voce “Manage Fields” in corrispondenza del nodo a cui siamo interessati applicare la possibilità di licenziarlo con questo sistma fatto in casa.
Ad esempio clicchiamo su “Manage Fields” in corrispondenza del “Page”, scorrendo anche qui la pagina aggiungiamo un “field” a cui applichiamo il nome “Licenza” e selezioniamo adesso il field “Node Reference”. A questo punto ci verrà chiesto quale dei nodi dovremo poter collegare, ovviamente selzioniamo il Content Type “Licenza” che abbiamo appena creato.
Anche qui possiamo un po' gestirci le altre impostazioni come meglio crediamo, personalmente ho messo come valore di default “None” cioè nessun nodo selezionato, mentre potrebbe essere utile selezionare una Licenza particolare come valore di default. A voi la scelta.
4. Conclusioni
Spero di essere stato chiaro e soprattutto utile, non è certo una guida che ci cambia la vita, ma probabilmente dimostra come con un po' di tempo a disposizione e un po' di logica possiamo creare funzionalità molto interessanti senza l'uso di alcun modulo aggiuntivo.
Vi elenco di seguito alcuni link del mio personale risultato di questa modalità di Licenziamento dei contenuti in perfetto stile Flickr.
Esempio
http://www.pillsofbits.com/guida/5-moduli-essenziali-un-progetto-basato-...
http://www.pillsofbits.com/licenza/attribuzione-non-commerciale-condivid...
http://www.pillsofbits.com/licenza/