Hosting Joomla - Alojamiento para Joomla, blog y vídeos Joomla

NEW YORK +1.888.815.4203 BARCELONA +34.902.009.386
Martes, 29 de Junio de 2010 16:05

Cómo desarrollar un componente de Google Maps en Joomla 1.6

por  David Noguera
Vota este articulo
(1 Voto)

Aprovechando la salida de Joomla 1.6 beta 4 nos hemos puesto manos a la obra y hemos empezado a indagar en las entrañas de Joomla 1.6. En principio os adelanto que no hay grandes cambios a la hora de desarrollar extensiones, y que el que sepa desarrollar extensiones para Joomla 1.5 no tendrá ningún problema con Joomla 1.6.

En este tutorial crearemos un extensión sencilla que recogerá de una BBDD información de lugares del mundo, y los mostrará pintados en un mapa de Google Maps. Nos hemos basado en el tutorial de Google Maps y PHP que publicó Google y lo hemos adaptado a Joomla 1.6 beta 4.

 

Los pasos que hemos seguido han sido los siguientes:

  1. Creamos  la tabla #__markers en la BBDD de Joomla 1.6.
  2. Introducimos datos de ejemplo en la tabla.
  3. Creamos  el punto de entrada del componente.
  4. Creamos  el controlador base.
  5. Creamos  la vista markers que contiene el div contenedor del mapa.
  6. Creamos  el modelo que obtiene datos de la tabla #__markers.
  7. Creamos  el task en el controlador base que devuelve la información de los lugares en formato XML.
  8. Creamos el fichero Javascript que se encargará de recoger la información en XML y pintar los marcadores en el mapa con el API de Google Maps.
  9. Testeamos que funcione todo correctamente.

Una vez vista la hoja de ruta del tutorial, vamos allá:

Creamos la tabla #__markers

CREATE TABLE `jos_markers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 60 ) NOT NULL ,
`address` VARCHAR( 80 ) NOT NULL ,
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
`type` VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;

Deberás cambiar jos por el prefijo de tu BBDD.

Introducimos los datos de ejemplo

INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Pan Africa Market', '1521 1st Ave, Seattle, WA', '47.608941', '-122.340145', 'restaurant');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Buddha Thai & Bar', '2222 2nd Ave, Seattle, WA', '47.613591', '-122.344394', 'bar');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('The Melting Pot', '14 Mercer St, Seattle, WA', '47.624562', '-122.356442', 'restaurant');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Ipanema Grill', '1225 1st Ave, Seattle, WA', '47.606366', '-122.337656', 'restaurant');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Sake House', '2230 1st Ave, Seattle, WA', '47.612825', '-122.34567', 'bar');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Crab Pot', '1301 Alaskan Way, Seattle, WA', '47.605961', '-122.34036', 'restaurant');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Mama\'s Mexican Kitchen', '2234 2nd Ave, Seattle, WA', '47.613975', '-122.345467', 'bar');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Wingdome', '1416 E Olive Way, Seattle, WA', '47.617215', '-122.326584', 'bar');
INSERT INTO `jos_markers` (`name`, `address`, `lat`, `lng`, `type`) VALUES ('Piroshky Piroshky', '1908 Pike pl, Seattle, WA', '47.610127', '-122.342838', 'restaurant');

Creamos el punto de entrada del componente

El punto de entrada se ubica en el fichero components/com_maps/maps.php, la convención es la misma que en Joomla 1.5, por lo que no tendremos dudas.

<?php
defined('_JEXEC') or die();

jimport('joomla.application.component.controller');

$controller = JController::getInstance('Maps');
$controller->execute(JRequest::getCmd('task', 'display'));
$controller->redirect();
?>

Si os fijáis a la hora de crear el punto de entrada ya no hace falta estar haciendo “malabarismos” para instanciar el controlador base u otro específico dependiendo del parámetro controller en la petición. Ahora todo esto se soluciona con el método getInstance. Aún así, si te gusta hacer malabarismos, podrás usar el método antiguo.

Creamos el controlador base

Esta parte es igual a Joomla 1.5. Dejo el código a continuación:

<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.controller');

/*
* Base controller class for Maps.
*/
class MapsController extends JController
{
public function display()
{
$document = JFactory::getDocument();

$lName     = JRequest::getWord('layout', 'default');
$view = $this->getView("markers", "html");

$view->assignRef('document', $document);
$view->display();
}
public function getMarkersXML()
{
$document = JFactory::getDocument();
$document->setMimeEncoding('text/xml');
$model = $this->getModel('markers');
$data = $model->getData();
echo "<markers>";
foreach($data as $marker){
echo '<marker ';
echo 'name="' . $this->parseToXML($marker->name) . '" ';
echo 'address="' . $this->parseToXML($marker->address) . '" ';
echo 'lat="' . $marker->lat . '" ';
echo 'lng="' . $marker->lng . '" ';
echo 'type="' . $marker->type . '" ';
echo '/>';
}
echo "</markers>";

}
private function parseToXML($htmlStr)
{
$xmlStr=str_replace('<','&lt;',$htmlStr);
$xmlStr=str_replace('>','&gt;',$xmlStr);
$xmlStr=str_replace('"','&quot;',$xmlStr);
$xmlStr=str_replace("'",'&#39;',$xmlStr);
$xmlStr=str_replace("&",'&amp;',$xmlStr);
return $xmlStr;
}
}
?>

Creamos la vista markers que contiene el div contenedor del mapa

Para crear la vista markers hay que proceder del mismo modo del que se hace en Joomla 1.5. Creamos el directorio markers, dentro del directorio views del componente. Dentro del directorio markers creamos el fichero view.html.php y el directorio tmpl donde se encuentran los layouts de la vista. En este caso crearemos el layout default.php. Podéis ver el código a continuación.

Fichero view.html.php

<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.view');

class MapsViewMarkers extends JView
{
public function display($tpl = null)
{
JHTML::_( 'behavior.mootools' );
$this->document->setTitle(JText::_('Lista de marcadores'));
$this->document->addScript("http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=true&amp;key=ABQIAAAAJP_tKIqNZxUwzi9ODnS-yxSF-qWcih2JzrSPTv88Wguu5XhySxTpN5Uw2o0ObTphklDWOKgTsuUfRw");
$this->document->addScript("components/com_maps/assets/maps.js");
parent::display($tpl);
}
}
?>

Fichero default.php

<h2 class="componentheading">Lista de marcadores</h2>
<div id="map" style="width: 600px; height: 400px"></div>

Creamos el modelo que obtiene datos de la tabla #__markers

Creamos el modelo markers, para ello creamos el fichero markers.php en el directorio models. Podéis ver el código del modelo a continuación.

<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.modelitem');

class MapsModelMarkers extends JModelItem
{
protected $_data = null;

public function getData(){

try {
$db = $this->getDbo();
$query = $db->getQuery(true);

$query->select('m.*');
$query->from('#__markers AS m');

$db->setQuery($query);

$data = $db->loadObjectList();

if ($error = $db->getErrorMsg()) {
throw new Exception($error);
}

if (empty($data)) {
throw new Exception(JText::_('COM_MAPS_ERROR_MARKER_NOT_FOUND'), 404);
}

$this->_data = $data;
}
catch (Exception $e)
{
$this->setError($e);
$this->_data = false;
}
return $this->_data;
}
}
?>

Creamos el task en el controlador base que devuelve la información de los lugares en formato XML

Implementamos el task getMarkersXML que usaremos para obtener un listado XML de los lugares introducidos en la base de datos. Usaremos la función privada parseToXML para evitar problemas con los caracteres que puedan chocar con el estándar XML

public function getMarkersXML()
{
$document = JFactory::getDocument();
$document->setMimeEncoding('text/xml');
$model = $this->getModel('markers');
$data = $model->getData();
echo "<markers>";
foreach($data as $marker){
echo '<marker ';
echo 'name="' . $this->parseToXML($marker->name) . '" ';
echo 'address="' . $this->parseToXML($marker->address) . '" ';
echo 'lat="' . $marker->lat . '" ';
echo 'lng="' . $marker->lng . '" ';
echo 'type="' . $marker->type . '" ';
echo '/>';
}
echo "</markers>";

}
private function parseToXML($htmlStr)
{
$xmlStr=str_replace('<','&lt;',$htmlStr);
$xmlStr=str_replace('>','&gt;',$xmlStr);
$xmlStr=str_replace('"','&quot;',$xmlStr);
$xmlStr=str_replace("'",'&#39;',$xmlStr);
$xmlStr=str_replace("&",'&amp;',$xmlStr);
return $xmlStr;
}

Creamos el fichero Javascript que se encargará de recoger la información en XML y pintar los marcadores en el mapa con el API de Google Maps

El fichero javascript maps.js es donde se encuentra el código que recoge esta información en XML y la pinta en el mapa usando el API de Google Maps. Usa iconos personalizados y genera ventanas de información para cada marcador. Podéis ver el código a continuación:

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(47.614495, -122.341861), 13);

GDownloadUrl("index.php?option=com_maps&task=getMarkersXML&format=raw", function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = createMarker(point, name, address, type);
map.addOverlay(marker);
}
});
}
}

function createMarker(point, name, address, type) {
var marker = new GMarker(point, customIcons[type]);
var html = "<b>" + name + "</b> <br/>" + address;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}

var customIcons = [];

document.addEvent( 'domready' ,  function() {

var iconBlue = new GIcon();
iconBlue.image = 'http://labs.google.com/ridefinder/images/mm_20_blue.png';
iconBlue.shadow = 'http://labs.google.com/ridefinder/images/mm_20_shadow.png';
iconBlue.iconSize = new GSize(12, 20);
iconBlue.shadowSize = new GSize(22, 20);
iconBlue.iconAnchor = new GPoint(6, 20);
iconBlue.infoWindowAnchor = new GPoint(5, 1);

var iconRed = new GIcon();
iconRed.image = 'http://labs.google.com/ridefinder/images/mm_20_red.png';
iconRed.shadow = 'http://labs.google.com/ridefinder/images/mm_20_shadow.png';
iconRed.iconSize = new GSize(12, 20);
iconRed.shadowSize = new GSize(22, 20);
iconRed.iconAnchor = new GPoint(6, 20);
iconRed.infoWindowAnchor = new GPoint(5, 1);

customIcons["restaurant"] = iconBlue;
customIcons["bar"] = iconRed;
load();

});

Probamos que funcione todo correctamente

Una vez seguidos estos pasos el componente debe funcionar correctamente. Como veis, la programación en Joomla 1.6 es muy similar a la de Joomla 1.5. Se han introducido nuevos elementos, en este pequeño tutorial hemos visto el objeto JQuery, no confundir con jQuery, el framework javascript. El objeto JQuery nos permitirá construir consultas SQL de una forma más sencilla. En Joomla 1.5 teníamos que construir las consultas manualmente y a veces esto se hacía complicado con consultas complejas, sobre todo a la hora de añadir las condiciones where, o los joins. También hemos visto que el punto de entrada se ha simplificado bastante, ahora se ha creado el método getInstance que simplifica el proceso y abstrae al programador de crear el punto de entrada, que aunque siempre acabábamos copiando y pegando, esta forma es más elegante que la anterior. Nos hemos dejado muchas cosas, como por ejemplo, ver el nuevo sistema de generación de formularios del API de Joomla 1.6, usando el objeto JModelForm, que nos permitirá crear los validadores usando definiciones en archivos XML. Conforme se vaya estabilizando el desarrollo de Joomla 1.6 iremos viendo más características sobre desarrollo web, que nos permitirán mantener nuestros desarrollos a la vanguardia de la tecnología Joomla.

Descargar los ficheros del tutorial (com_maps.zip)

Ultima modificacion el Sábado, 05 de Febrero de 2011 22:10

¡Descubre nuestros Packs!


Pack Tienda Joomla

Pack Empresa Joomla

Pack Periódico o Revista Joomla

Testimonios de Clientes

Buscador Joomla

Cargando...

Webempresa en Facebook

Quieres estar al día en Joomla?
Haz clic en "Me gusta"


Canales Webempresa

Twitter_Facebook_Youtube_Feed_

Notícias Joomla en tu Email

noticias Joomla
Suscríbete Ahora!
Código:
Joomla : Hosting Joomla - Alo

Artículos en tu lector RSS

Suscríbete a nuestro Feed RSS

Servicios que ofrecemos para Joomla :
Hosting JoomlaHosting Joomla
Servidores Joomla especializados.
Soporte Joomla 24x7x365
hosting_joomla Reseller Joomla
Especial para Diseñadores Joomla. Olvídate del Hosting de tus Clientes
ayuda JoomlaAprende Joomla
Formación en Joomla 2.5, Virtuemart 2.0 y de las extensiones más populares
Desarrollo JoomlaPacks Joomla
Múltiples diseños profesionales.
Tu Web Joomla por 299€