Archivio della categoria: Web Programming & Html & Javascript

Esperimenti e tutorial per Html5 ,Javascript e librerie varie.

Tomcat 7, jndi datasource ed eclipse

Piccola guida per la risoluzione di un banale task ma che spesso crea problemi, e cioè la definizione di un datasource jdbc su Tomcat .
Nel caso specifico utilizzo un datasource con driver SqlServer di Microsoft.
La libreria Microsoft contenente il driver jdbc (nel mio caso la sqljdbc4.jar), deve essere messa nella cartella lib del server tomcat.
Va poi configurata la risorsa jndi nel file server.xml nella cartella conf di tomcat, aggiungendo ad esempio questo :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--?xml version="1.0" encoding="UTF-8"?-->
<!--contenuto vario del nostro file server,trovare l'elemento globalnamingresources e aggiungere la nostra resource-->
<GlobalNamingResources>
<Resource name="jdbc/testdb" auth="Container" type="javax.sql.DataSource"
        username="kiraya"
        password="kiraya"
        factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
        url="jdbc:sqlserver://xx.xx.xx.xx:1433;DatabaseName=MYDB"
        maxActive="50"
        maxIdle="10"
        maxWait="15000"
        removeAbandoned="true"
       removeAbandonedTimeout="30"
       logAbandoned="true"
        validationQuery="select 1" />

</GlobalNamingResources>

Fatto questo, per poter rendere visibile al contesto web della nostra webapplication il driver, senza essere costretti a registrarlo manualmente tramite il DriverManager, mettiamo un resource-link o copiamo direttamente l’xml della definizione resource sopra inserita, nel file context.xml della cartella conf di tomcat, od in un file context.xml nella cartella META-INF della webapplication.
Dovendo rilasciare l’applicazione su diversi application server, preferisco non portare specifici files di configurazione nell’applicazione(ove possibile) e quindi lascio il file context.xml nella cartella config del server tomcat.

Contenuto del context.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
--><!-- The contents of this file will be loaded for each web application --><Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <Resource name="jdbc/testdb" auth="Container" type="javax.sql.DataSource"
        username="kiraya"
        password="kiraya"
        factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
        url="jdbc:sqlserver://xx.xx.xx.xx:1433;DatabaseName=MYDB"
        maxActive="50"
        maxIdle="10"
        maxWait="15000"
        removeAbandoned="true"
       removeAbandonedTimeout="30"
       logAbandoned="true"
        validationQuery="select 1" />    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
        on session expiration as well as webapp lifecycle) -->
    <!--
   <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
   -->

</Context>

Fatto questo, possiamo utilizzare una lookup jndi nella maniera classica per ottenere una connessione db.

1
2
3
javax.naming.InitialContext context = new javax.naming.InitialContext();
DataSource ds = (DataSource)context.lookup("java:/comp/env/jdbc/testdb");
Connection conn = ds.getConnection();

Se tomcat è configurato come server Runtime dentro eclipse, e quindi lo start e stop viene fatto da li, allora il file context da modificare non è quello della cartella conf del server ma quella della versione gestita da Eclipse, generalmente contenuta nel workspace, nella cartella Server..

Custom Sidebars in WordPress & Articoli singoli

Ci sono decine di plugin che permettono di gestire le sidebar di WordPress, in maniera dinamica associandole alle categorie, o alle pagine , altri tramite logica configurabile, altri banalmente tramite un custom tag nella pagina.

Il problema fondamentale è che nei template standard non c’e’ supporto per le sidebar sulla visualizzazione di un singolo articolo.

Per sbloccare questa cosa bisogna apportare delle modifiche ai files del nostro tema.

Innanzitutto bisogna abilitare la sidebar nella pagina singola.

Apriamo il file single.php e aggiungiamo la funzione get_sidebar() prima della get_footer()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
/**
* The Template for displaying all single posts.
*
* @package WordPress
* @subpackage Twenty_Eleven
* @since Twenty Eleven 1.0
*/


get_header(); ?>

<div id="primary">

<div id="content" role="main">

<?php while ( have_posts() ) : the_post(); ?>

<nav id="nav-single">

<h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>

<span class="nav-previous"><?php previous_post_link( '%link', __( '<span class="meta-nav">&larr;</span> Previous', 'twentyeleven' ) ); ?></span>

<span class="nav-next"><?php next_post_link( '%link', __( 'Next <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></span>

</nav><!-- #nav-single -->

<?php get_template_part( 'content', 'single' ); ?>

<?php comments_template( '', true ); ?>

<?php endwhile; // end of the loop. ?>

</div><!-- #content -->

</div><!-- #primary -->

<?php get_sidebar(); ?>

<?php get_footer(); ?>

Ora anche gli articoli quando visualizzati da soli (quindi non in modalità archivio, ricerca o homepage), avranno accesso alle sidebar.

Bisogna a questo punto aggiungere una funzione di decorazione del dom di pagina affinche vengano impostate le classi giuste del css altrimenti la sidebar verrà mostrata sotto l’articolo.

Apriamo quindi il file functions.php del nostro tema e in coda, aggiungiamo questa funzione:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
add_filter('body_class', 'fix_body_class_for_sidebar', 20, 2);

function fix_body_class_for_sidebar($wp_classes, $extra_classes) {

if( is_single() || is_page() ){

if (in_array('singular',$wp_classes)){

foreach($wp_classes as $key => $value) {

if ($value == 'singular')

unset($wp_classes[$key]);

}

}

}

return array_merge($wp_classes, (array) $extra_classes);

}

Fatto questo, il gioco è fatto.

Consiglio di usare poi, Content Aware Sidebar o Dynamics Sidebar come plugin per la gestione delle sidebar.

 

 

Multiple marker e Multiple infoWindow con Google Maps

Tempo fa mi sono imbattuto in un problema che poi come sempre si è risolto in maniera abbastanza ovvia (basta studiare), e che si è riproposto ultimamente a degli amici, per cui pubblico qui la soluzione.

Le Api di google maps, permettono l’uso (nel caso delle mappe dinamiche), di markers che direttamente in javascript ci fanno aggiungere i segnaposti sulle mappe.

Ora ogni segnaposto è previsto di una property text per mostrare ad esempio l’indirizzo passando sopra un marker. Se vogliamo invece mostrare una finestra con markup html all’interno allora dobbiamo utilizzare la InfoWindow, messa sempre a disposizione da google maps.

Per far in modo che questa infowindow sia posizionata e aperta al click di un marker dobbiamo registrare l’evento per ogni marker.

La documentazione di esempio di google maps fa l’esempio con un solo marker quindi erroneamente indica questo:

1
2
3
4
5
6
7
8
9
10
11
google.maps.event.addListener(marker, 'click', function() {

infowindow.close();

infowindow.setContent("markup html");

infowindow.setPosition(marker.position);

infowindow.open(map, marker);

});

Il problema è che se marker è l’istanza corrente di un marker creato all’interno di un ciclo, quando andiamo a registrare il listener per l’evento “onclick” non dobbiamo riferirci a lui in questo modo “marker.position” per passare la posizione, perche cosi facendo passiamo la posizione dell’ultimo marker del ciclo.. Dobbiamo usare il this.. in modo che ogni listener abbia il riferimento alla sua istanza di marker.

(Si questa cavolata ha fatto perdere diverse ore a piu persone)

Praticamente quando andiamo a creare i nostri marker da mostrare, creiamo l’evento onClick per questo marker in questo modo:

1
2
3
4
5
6
7
8
9
10
11
12
13
//dopo aver creato un marker

google.maps.event.addListener(marker, 'click', function() {

infowindow.close();

infowindow.setContent(this.html);

infowindow.setPosition(this.position);

infowindow.open(map, this);

});

la property html sul marker non esiste. La uso io (in javascript gli oggetti non sono altro che degli insiemi di property che possono essere manipolati dinamicamente) in genere durante la generazione dei markers per passare il markup che deve essere contenuto nella infowindow, cosi da non settare la property text e disabilitare il baloon standard.

 

Esempio di marker con la InfoWindow:

That’s All Folks..