No suena como una labor muy problemática, pero en realidad involucra dos temas interesantes y me parecio útil mostrarlos:
- Crear la lista con el formato requerido en base al feed del sito.
- Conseguir que un Iframe se comunique con su contenedor pariente, a pesar de que son de dominios distintos.
Que un Iframe se comunique con su pariente no es mayor problema si usamos Jquery y los archivos están en el mismo dominio, pero cuando son de dominios distintos se llega a un callejón sin salida. Afortunadamente encontre una manera de esquivar el obstaculo y la explicare al final. De momento empezare con la creacion de la lista.
Para hacer un menú expandible me inspire en este snippet de bootstrap: https://bootsnipp.com/snipps/collapsible-tree-menu En realidad es muy sencillo de implementar con las librerías de bootstrap, el problema esta en como extraer una lista con las respectivas clases y ID's que se necesitan. Para algo como esto pensé en extraerlo con el Feed del sitio. El feed me proporciona la información que necesito para crear mi lista: años, meses, nombres y enlaces.
Probablemente exista una manera mas eficiente de crear la lista, pero esto es lo que salio de mi cabeza al momento:
<?php
$xml_array = array();
$xml_clean = array();
function parserFeed($feedurl) {
$xmlObject = simplexml_load_file($feedurl) or die ("Unable to load XML file!");
$xmlObject = $xmlObject ->channel->item;
$index = 0;
foreach( $xmlObject as $node ) {
$link = (string) $node->link; //enlace al post
$title = (string) $node->title; //titulo
//Get the date
$postyear = date('Y',strtotime($node->pubDate));
$postmonth = date('n',strtotime($node->pubDate));
$node_item = array(
'indexposition' => $index,
'year' => $postyear,
'month' => $postmonth,
'title' => $title,
'path' =>$link
);
array_push($GLOBALS[ 'xml_array' ], $node_item);
$index++;
}
fixArray ( $GLOBALS[ 'xml_array' ] );
}
function fixArray ($source) {
$nodeyear = '0';
$amonth = '0';
$currentYear = array();
$currentMonth = array();
$currentPost = array();
$yearTotalPosts = 0;
$monthTotalPosts = 0;
/* ------------------------------------------- */
/* Itinerando por los años en la lista de post */
/* ------------------------------------------- */
for ($a = 0; $a < count($source); $a++) {
if ($nodeyear != $source[$a]['year']) {
$currentYear[$a] = array( $source[$a]['year'] );
/* ------------------------------------------- */
/* Itinerando por los meses en la lista de post */
/* ------------------------------------------- */
for ($e = 0; $e<count($source); $e++) {
if ( $source[$e]['year'] == $source[$a]['year'] ) {
if ( $amonth != $source[$e]['month'] ) {
$currentMonth[$e] = array( $source[$e]['month'] );
/* ------------------------------------------- */
/* Itinerando entre los post */
/* ------------------------------------------- */
for ($i = 0; $i<count($source); $i++) {
if ( $source[$i]['year'] == $source[$a]['year'] && $source[$i]['month'] == $source[$e]['month']) {
$currentPost[$i] = array( 'atitle' => $source[$i]['title'], 'alink' => $source[$i]['path'] );
array_push($currentMonth[$e], $currentPost[$i] );
$yearTotalPosts++;
$monthTotalPosts++;
}
}
array_push($currentYear[$a], array('month' => $currentMonth[$e], 'monthtotal' => $monthTotalPosts) );
$amonth = $source[$e]['month'];
}
$monthTotalPosts = 0;
}
}
array_push($GLOBALS[ 'xml_clean' ], array ('thisyear' => $currentYear[$a], 'yeartotal' => $yearTotalPosts ) );
//------------------YEAR END-----------------------;
$nodeyear = $source[$a]['year'];
$amonth = '0';
}
$yearTotalPosts = 0;
}
listCreator( $GLOBALS[ 'xml_clean' ] );
}
function listCreator( $cleanArray ) {
$cleanArraySort = array();
krsort( $cleanArray );
foreach ($cleanArray as $key => $val) {
array_push($cleanArraySort, $cleanArray [$key] );
}
echo '<div class="wrapper" id="wrapper">';
echo '<ul id="holder" class="nav nav-list">';
$yearCounter = count($cleanArray);
for ($a = 0; $a<count($cleanArraySort); $a++) {
echo '<li><label class="tree-toggler nav-header">' . $cleanArraySort[$a]['thisyear'][0]. '(' . $cleanArraySort[$a]['yeartotal']. ')</label>';
$nodeYear = $cleanArraySort[$a]['thisyear'];
echo count( $nodeYear ) > '0' ? '<ul class="nav nav-list tree">' : '';
for ($e = 1; $e < count( $nodeYear ); $e++) {
echo '<li><label class="tree-toggler nav-header">'. getmonth ( $nodeYear[$e]['month'][0] ) .'(' . $nodeYear[$e]['monthtotal'] .')</label>';
$nodeMonth = $nodeYear[$e]['month'];
echo count( $nodeMonth ) > '0' ? '<ul class="nav nav-list tree">' : '';
for ($i = 1; $i < count( $nodeMonth ); $i++) {
echo '<li>';
echo '<a target="_top" title=" '.$nodeMonth[$i]['atitle'].' " href=" '. $nodeMonth[$i]['alink'] .' ">';
echo $nodeMonth[$i]['atitle'] ;
echo '</a>';
echo '</li>';
}
echo count( $nodeMonth ) > '0' ? '</ul>' : '';
echo '</li>';
}
echo count( $nodeYear ) > '0' ? '</ul>' : '';
echo '</li>';
}
echo '</ul>';
echo "</div>";
}
function getmonth($value) {
switch($value){
case '1':
$month = "Enero";
break;
case '2':
$month = "Febrero";
break;
case '3':
$month = "Marzo";
break;
case '4':
$month = "Abril";
break;
case '5':
$month = "Mayo";
break;
case '6':
$month = "Junio";
break;
case '7':
$month = "Julio";
break;
case '8':
$month = "Agosto";
break;
case '9':
$month = "Septiembre";
break;
case '10':
$month = "Octubre";
break;
case 11:
$month = "Noviembre";
break;
case 12:
$month = "Diciembre";
break;
}
return $month;
}
parserFeed ( 'http://www.blogdev.bengalamedialab.com/feeds/posts/default?alt=rss' );
?>
Con esto creamos un archivo php que resida en nuestro servidor externo, que funcione por si solo como el ejemplo del snippet. La diferencia esta en que en el evento que realiza la expansión del árbol debemos colocar un pequeño código que dispara una "alerta" o un "aviso" para que pueda ser usado luego en el parent que lo contendrá como Iframe. Este evento podrá ser escuchado por el contenedor y podrá autoajustarse según el alto de la lista ya expandida. Este es el código necesario, usando Jquery:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
function adjust_iframe_height(){
var triggerMessage = $('.wrapper').height() + ",file_list";
parent.postMessage( triggerMessage ,"http://www.blogdev.bengalamedialab.com/");
console.log('heigth is: ' + triggerMessage);
}
$(document).ready(function () {
$('label.tree-toggler').click(function () {
$(this).parent().children('ul.tree').toggle(300, function() {
adjust_iframe_height();
});
});
adjust_iframe_height();
});
Y no olvidemos que Bootstrap también es necesario en el archivo:
<div class='well'>
<h3 class='title'>Archivos</h3>
<div class="ifraneholder" >
<iframe class="autoHeight" id="autoHeight" src="http://URLEXTERNO/core/php/blogdev/post_parse.php" scroll="auto" marginheight="0" frameborder="0" ></iframe>
</div>
</div>
Este bloque de JavaScript tambien es necesario en nuestro template:
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child window
eventer(messageEvent,function(e) {
var message = new Array();
var message_height = 0;
var message_source = "";
message = e.data.split(",");
console.log('data in place: ' + message[0]);
message_height = message[0];
message_source = message[1];
switch( message_source ) {
case "file_list":
$('#autoHeight').height( message_height );
$('.ifraneholder').height( message_height );
break;
case "twitter_feed":
$('#tweet_holder').height( message_height );
$('.twitter_holder').height( message_height );
break;
case "contact_form":
$('#contact_holder').height( message_height );
$('.contact_holder').height( message_height );
break;
}
},false);
Como esta función es usada en otros elementos con Iframe estoy usando un switch que determina que Iframe es el que esta enviando el aviso.Estos enlaces me ayudaron mucho para resolver el problema de Iframe en dominios externos:
0 comentarios:
Publicar un comentario