====== Implementació a Wordpress d'un menú d'opcions amb desplaçament automàtic segons la posició del ratolí ====== * Podeu veure aquesta solució implementada per mi a http://www.traxmedia.es * Us pot ser útil consultar: * els enllaços relatius a Creació web dins les [[enllacos:lnk-otr-os#creacio_web|generalitats de codi obert]] * els enllaços relatius a Wordpress dins l'[[enllacos:lnk-cms|apartat de CMS]] ===== Introducció ===== Aquest tutorial explica com fer un menú semblant o equiparable a [[http://valums.com/wp-content/uploads/2009/02/menu/final.htm|aquest]] dins de Wordpress, i es basa en la documentació proveïda [[http://valums.com/scroll-menu-jquery/|al mateix lloc web]] però també necessàriament en moltes altres pàgines visitades. Malgrat la obvietat, pot estalviar algun maldecap fer saber que aquesta solució és útil quan l'espai que el conjunt de les opcions del menú ocupa és més gran que la grandària del menú definida dins el CSS. Si les opcions ocupen menys que el total del menú, òbviament no hi ha cap necessitat de desplaçar res, i la solució proposada no ho farà. Al llarg de la implementació d'aquest menú a la pàgina d'un dels meus clients, em vaig trobar amb problemes principalment a causa del fet que a la mateixa pàgina ja hi havia un altre element que, com aquest menú, feia ús de llibreries //extra// de javascript, en aquest cas jQuery, i això semblava causar unes obscures incompatibilitats que, evidentment, em va caldre resoldre. Bé, de fet em vaig trobar amb problemes molt abans, perquè pel camí he provat moltes altres opcions de desplaçament que m'han donat problemes similars, però al final he optat per aquesta. == Per què aquesta opció? == * Perquè em va semblar la més senzilla de fer funcionar. És a dir, aquella en què entraven en joc menys variables. * Perquè em va semblar molt útil no haver d'obligar l'usuari a anar fent clic a les molestes sagetes (molestes quan en pots prescindir, és clar!) * Perquè permet utilitzar tantes instàncies d'un menú amb desplaçament (en altres paraules, tants menús) com sigui necessari de manera fàcil i lògica, i permet integrar fàcilment el CSS necessari per a l'script amb el que nosaltres vulguem definir o tinguem ja definit. * Perquè permet incorporar a l'estat de //pas del cursor per sobre// les icones/elements del menú (on mouse over) text explicatiu de la icona. ===== Comencem ===== La primera qüestió que cal tenir resolta és on anirà ubicat aquest menú. Això no s'aborda en aquest tutorial i és quelcom que hauràs resolt posicionant amb CSS. En el meu cas, el codi que necessitava per fer funcionar l'script i pel que fa a les etiquetes XHTML, dins els altres //div// posicionats oportunament, tenia aquest aspecte:
* El //div class="retallMenuSupEsquerre"// és el primer element imprescindible per a l'script. Després veurem que el podem modificar amb CSS, però també haurem de respectar algunes parts del CSS original * El segon element imprescindible és un //ul// que sigui de la mateixa classe que el //div// * Després tenim uns elements de llista, tants com opcions hagi de tenir el menú. No cal ser gaire llest per endevinar que aquest menú tindria 3 opcions: quelcom 1, quelcom 2 i quelcom 3. * Dins de cada element de llista hi ha un element d'enllaç i, dins aquest darrer, una imatge: * L'element d'enllaç (//a//) té una etiqueta bloginfo que imprimeix la url actual del Wordpress, de tal manera que podem enllaçar amb posts i pàgines amb una mena de ruta pseudo-relativa, * I la imatge es crida també fent ús del bloginfo i es troba dins el directori //images// del directori de la plantilla activa en aquell moment. Podria ser, però, qualsevol altre directori, sempre i quan la ruta estigui convenientment especificada. == Inclusió del CSS == Quan ja hem introduït els elements de l'XHTML, hem de declarar aquestes classes i especificacions en el CSS, a fi que després la funció de javascript pugui actuar d'acord amb els valors assignats. De la pàgina de la documentació extrec directament això, només canviant el nom de la classe per defecte pel nom que he utilitzat en el meu exemple: div.retallMenuSupEsquerre { /* Set it so we could calculate the offsetLeft */ position: relative; height: 145px; width: 500px; /* Add scroll-bars */ overflow: auto; } ul.retallMenuSupEsquerre { display: block; height: 110px; /* Max width here, for users without Javascript */ width: 1500px; padding: 15px 0 0 15px; /* Remove default margin */ margin: 0; background: url('navigation.png'); list-style: none; } .retallMenuSupEsquerre li { display: block; float: left; padding: 0 4px; } .retallMenuSupEsquerre a { display: block; text-decoration: none; } .retallMenuSupEsquerre span { display: none; margin-top: 3px; text-align: center; font-size: 12px; color: #fff; } .retallMenuSupEsquerre a:hover span { display: block; } .retallMenuSupEsquerre img { border: 3px #fff solid; -webkit-border-radius: 3px; -moz-border-radius: 3px; } .retallMenuSupEsquerre a:hover img { filter:alpha(opacity=50); opacity: 0.5; } Bona part d'aquests paràmetres es poden modificar al vostre gust, i fins i tot pot haver-n'hi alguns que no siguin estrictament necessaris. Conserveu, però, en el seu lloc la propietat //overflow// i el seu valor //auto// dins la definició de la classe //div.retallMenuSupEsquerre//, ja que el javascript ha de trobar definit aquest valor a fi de poder eliminar les barres d'scroll i desencadenar el desplaçament automàtic. Internet Explorer no executarà correctament l'script si falta aquest paràmetre, tot i que altres navegadors semblen ser més tolerants. Tingueu present també que les propietats //-webkit-border-radius// i //-moz-border-radius// no estan incloses, diria, a la versió 2 de l'especificació de CSS. No estic segur si la propietat //filter// tampoc. ===== Inclusió de les funcions de Javascript ===== Com hem dit, aquest efecte és possible gràcies a les llibreries jQuery, que proporcionen un accés optimitzat a funcions i possibilitats avançades de Javascript. Aquestes llibreries, siguin solucions tipus jQuery o d'altres possibles com Prototype, s'han de referenciar. Per tant, tenim per una banda l'script que fa la //màgia// del moviment dins el menú, i per l'altra les llibreries que aquest script necessita per funcionar. Tots dos elements, l'script i la referenciació a les llibreries, han d'anar inclosos dins l'element //head// de la pàgina, ja que aquest element comprèn tots els altres que necessiten ser carregats abans que els continguts pròpiament de la pàgina. L'element //head// es troba dins el fitxer //header.php//, per defecte, però pot ser que vosaltres l'hagueu inclòs dins una única pàgina //index.php//. Ja veurem, però, que la referenciació a les llibreries necessita algunes precisions i correccions, des del meu punt de vista, respecte el que es diu a la pàgina de la documentació original. Incloure l'script és tan trivial com enganxar el codi següent dins el //head// i assegurant-nos que ho fem després (en l'estructura del document) de la crida codi de l'script: * Si observeu les ocurrències de //retallMenuSupEsquerre// al cos de l'XHTML, al CSS i finalment a l'anterior script, podreu entrellucar perquè és tan fàcil implementar aquesta solució a les nostres pròpies definicions de CSS. Si volguessim afegir menús addicional amb desplaçament de les seves opcions, (per exemple, un menú de classe //retallMenuSupDret//) només hauríem d'afegir sengles definicions de classe dins * el cos de l'XHTML (el menú pròpiament) * el CSS (la definició gràfica del menú) * l'script dins el //head// (el codi de què ha de passar dins el menú) * D'aquesta manera, si per exemple tinguessim tres menús amb desplaçament utilitzant aquesta solució, tindriem * tres definicions, una per cada menú, dins el cos de l'XHTML * tres conjunts de definicions dins el CSS, un per a cada classe de cada un dels menús * tres scripts que especificarien què ha de passar dins el menú Si heu repassat la [[http://valums.com/wp-content/uploads/2009/02/menu/final.htm|documentació original]] observareu que es fa servir $(document).ready(function() en lloc de jQuery(document).ready(function() Als [[enllacos:lnk-cms|enllaços esmentats al principi sobre CMS]] podeu veure diverses pàgines i articles que aborden per què majoritàriament cal evitar fer servir $ en les crides a jQuery i utilitzar directament //jQuery//. Però el problema no s'acaba aquí. Resulta que la documentació original indica que cal **referenciar** jQuery utilitzant el següent element de referenciació d'scripts: El que això revela, si mirem les tripes de la nostra instal·lació de Wordpress en el cas de la versió 2.7, és que es fa servir una versió de jQuery més moderna de la que per defecte hi ha instal·lada. D'altra banda, alguns [[enllacos:lnk-cms|enllaços esmentats al principi sobre CMS]] aborden la qüestió de quina és la manera òptima de fer aquesta referenciació a les llibreries externes (encara que no siguin jQuery) en Wordpress. I la conclusió és que, a més del fet que des del meu punt de vista no és convenient haver de dependre d'uns fitxers proporcionats per pàgines de Google, cal referenciar les llibreries no dins el document header.php o index.php sinó en un fitxer //ad hoc// que hi ha a la instal·lació de Wordpress: //functions.php//, que es troba al directori de la plantilla //default// de Wordpress. L'aspecte que té la primera línia d'aquest fitxer en el meu cas és el següent: wp_enqueue_script('jqueryUpd', '/wp-includes/js/jquery-1.3.2.min.js'); Com veieu, aquí es fa ús de la instrucció wp_enqueue_script per tal de referenciar globalment al sistema l'ús de la llibreria //jquery-1.3.2.min.js//. El que he fet simplement és descarregar de la pàgina proporcionada a la documentació el fitxer .js en qüestió, i posar-lo al directori que conté totes les llibreries js de Wordpress. //jqueryUpd// és un identificador arbitrari que assigno a la llibreria que vull carregar i que ve a significar quelcom per l'estil de //jQuery Updated//. No estic segur que es pugui ser tant arbitrari en tots els casos, però en aquest no sembla donar problemes. Si volguessim referenciar altres llibreries, relacionades o no amb jQuery, només caldria procedir de manera anàloga i referenciar-ho a //functions.php//. Tingueu present que les darreres versions de Wordpress ja vénen amb força llibreries instal·lades per defecte, com Prototype i scriptaculous, però probablement calgui referenciar-les explícitament per utilitzar-les. Podeu veure més informació sobre wp_enqueue_script i totes aquestes qüestions abordades aquí dalt als enllaços sobre CMS que he indicat abans (encara no has obert la pàgina a una altra pestanya?!) El fet que es referencïin en un fitxer extern aquestes llibreries és el motiu pel qual els scripts han d'anar després de ja que aquesta és el codi que carrega, entre altres coses, les instrucciones incloses dins de functions.php. Per tant, quan l'script es declari ja han d'haver estat declarades les referències a les llibreries. Si no fos així, l'script no les podria utilitzar. Pot ser revelador que mireu el codi font de la pàgina amb el PHP ja executat. Veureu que l'intèrpret ha inclòs les referències dins el fitxer functions.php en elements //script src="ruta/alavostra/llibreria"// al document interpretat. ===== Finalment ===== Fet això el menú hauria de funcionar. Recomano molt que observeu i estudieu el codi font de la [[http://valums.com/wp-content/uploads/2009/02/menu/final.htm|pàgina d'exemple del menú]], tant per provar-ne el funcionament abans de tirar-vos-hi de cap, com per depurar els problemes si quelcom no funciona. Des del meu punt de vista, sovint és interessant assegurar-se que les coses funcionen fora d'un entorn dinàmic (sense parts interpretades amb PHP, per tant, ni inclusions a llibreries a través d'obscurs //wp_enqueue_script//) abans de passar a un entorn dinàmic. Amb una mica de sort, doncs, tot el que restarà serà barallar-se amb el CSS perquè s'ajusti a les vostres necessitats