Joomla.it Forum
Non solo Joomla... => Sviluppo => : claudiofollonica 03 Feb 2013, 18:55:45
-
Salve a tutti,
da qualche tempo mi sto dedicando all'ottimizzazione del mio sito joomla (www.studiodestasio.it) per la rimozione dei contenuti duplicati cercando di impedire l'indicizzazione degli url non SEF.
Fra le altre cose ho rivisto il file robots.txt inserendo determinate pagine che NON voglio siano indicizzate.
Tutto ok ma gli strumenti webmaster di google mi segnalano che taluni indirizzi della sitemap generata da XMAP sono bloccati da robots.txt. E' solo un warning ma mi piacerebbe risolvere comunque questa anomalia…
In effetti basterebbe che XMAP, al momento di generare la pagina XML, escludesse gli url bloccati da robots.txt
Non conosco praticamente nulla di PHP ma capisco che la cosa sarebbe veramente molto semplice.
Il file che genera la mappa XML è /components/com_xmap/views/xml/tmpl/default_class.php
Immagino che sarebbe sufficiente:
1) aprire robots.txt
2) caricare linea per linea e se questa contiene "Disallow: " prelevare la parte destra e memorizzarla in un array
3) a questo punto prima di "scrivere" ogni url verificare che questo non contenga una delle stringhe memorizzate nell'array del punto 2
Ora, può anche darsi che riesca a farlo da solo ma senza conoscere PHP chissà quando ci potrei impiegare…
C'è qualche anima pia che in 5 minuti mi da qualche dritta? ;)
-
Speravo in qualche suggerimento....
comunque, cercando sul web, ho trovato una funzione che poteva fare al caso mio.
Non è una soluzione elegante perché viene invocata ogni volta che c'è da scrivere un url nella sitemap xml (ed ogni volta carica robots.txt, fa il controllo ecc. ecc. con ovvio spreco di risorse, ma joomlahost è talmente veloce che quasi 400 url li processa istantaneamente!!).
In questo modo per escludere link specifici dalla sitemap generata da XMAP è sufficiente inserirli in robots.txt
Abbiate pazienza se ho scoperto l'acqua calda ma intanto sono contento di vedere google che mi da semaforo verde....
Ecco come ho modificato /components/com_xmap/views/xml/tmpl/default_class.php
(la funzione è l'ultima, robots_allowed, e viene invocata alla riga 96; adesso mi piacerebbe ottimizzarla facendo in modo che robots.txt venga aperto una sola volta, ad esempio, eliminando il controllo dell'user-agent che non serve ecc... sapessi come fare ovviamente ;))
<?php
/**
* @version $Id$
* @copyright Copyright (C) 2005 - 2009 Joomla! Vargas. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @author Guillermo Vargas (guille@vargas.co.cr)
*/
// No direct access
defined('_JEXEC') or die;
require_once(JPATH_COMPONENT . '/displayer.php');
class XmapXmlDisplayer extends XmapDisplayer
{
/**
*
* @var array Stores the list of links that have been already included in
* the sitemap to avoid duplicated items
*/
var $_links;
/**
*
* @var string
*/
var $view = 'xml';
protected $showTitle = false;
protected $showExcluded = false;
/**
*
* @var int Indicates if this is a google news sitemap or not
*/
var $isNews = 0;
function __construct($config, $sitemap)
{
parent::__construct($config, $sitemap);
$this->uids = array();
$this->defaultLanguage = strtolower(JFactory::getLanguage()->getTag());
if (preg_match('/^([a-z]+)-.*/',$this->defaultLanguage,$matches) && !in_array($this->defaultLanguage, array(' zh-cn',' zh-tw')) ) {
$this->defaultLanguage = $matches[1];
}
$this->showTitle = JRequest::getBool('filter_showtitle', 0);
$this->showExcluded = JRequest::getBool('filter_showexcluded', 0);
$db = JFactory::getDbo();
$this->nullDate = $db->getNullDate();
}
/**
* Prints an XML node for the sitemap
*
* @param stdclass $node
*/
function printNode($node)
{
$node->isExcluded = false;
if ($this->isExcluded($node->id,$node->uid)) {
if (!$this->showExcluded || !$this->canEdit) {
return false;
}
$node->isExcluded = true;
}
if ($this->isNews && (!isset($node->newsItem) || !$node->newsItem)) {
return true;
}
// Get the item's URL
$link = JRoute::_($node->link, true, @$node->secure==0? -1: $node->secure);
if (!isset($node->browserNav))
$node->browserNav = 0;
if ($node->browserNav != 3 // ignore "no link"
&& empty($this->_links[$link])) { // ignore links that have been added already
$this->count++;
$this->_links[$link] = 1;
if (!isset($node->priority))
$node->priority = "0.5";
if (!isset($node->changefreq))
$node->changefreq = 'daily';
// Get the chancefrequency and priority for this item
$changefreq = $this->getProperty('changefreq', $node->changefreq, $node->id, 'xml', $node->uid);
$priority = $this->getProperty('priority', $node->priority, $node->id, 'xml', $node->uid);
$link=str_replace('/forum/home/','/forum/',$link);
if (robots_allowed($link,"*")) {
echo '<url>' . "\n";
echo '<loc>', $link, '</loc>' . "\n";
if ($this->canEdit) {
if ($this->showTitle) {
echo '<title><![CDATA['.$node->name.']]></title>' . "\n";
}
if ($this->showExcluded) {
echo '<rowclass>',($node->isExcluded? 'excluded':''),'</rowclass>';
}
echo '<uid>', $node->uid, '</uid>' . "\n";
echo '<itemid>', $node->id, '</itemid>' . "\n";
}
$modified = (isset($node->modified) && $node->modified != FALSE && $node->modified != $this->nullDate && $node->modified != -1) ? $node->modified : NULL;
if (!$modified && $this->isNews) {
$modified = time();
}
if ($modified && !is_numeric($modified)){
$date = new JDate($modified);
$modified = $date->toUnix();
}
if ($modified) {
$modified = gmdate('Y-m-d\TH:i:s\Z', $modified);
}
// If this is not a news sitemap
if (!$this->isNews) {
if ($modified){
echo '<lastmod>', $modified, '</lastmod>' . "\n";
}
echo '<changefreq>', $changefreq, '</changefreq>' . "\n";
echo '<priority>', $priority, '</priority>' . "\n";
} else {
if (isset($node->keywords)) {
$keywords = htmlspecialchars($node->keywords);
} else {
$keywords = '';
}
if (!isset($node->language) || $node->language == '*') {
$node->language = $this->defaultLanguage;
}
echo "<news:news>\n";
echo '<news:publication>'."\n";
echo ' <news:name>'.(htmlspecialchars($this->sitemap->params->get('news_publication_name'))).'</news:name>'."\n";
echo ' <news:language>'.$node->language.'</news:language>'."\n";
echo '</news:publication>'."\n";
echo '<news:publication_date>', $modified, '</news:publication_date>' . "\n";
echo '<news:title><![CDATA['.$node->name.']]></news:title>' . "\n";
if ($keywords) {
echo '<news:keywords>', $keywords, '</news:keywords>' . "\n";
}
echo "</news:news>\n";
}
echo '</url>', "\n";
}
} else {
return empty($this->_links[$link]);
}
return true;
}
/**
*
* @param string $property The property that is needed
* @param string $value The default value if the property is not found
* @param int $Itemid The menu item id
* @param string $view (xml / html)
* @param int $uid Unique id of the element on the sitemap
* (the id asigned by the extension)
* @return string
*/
function getProperty($property, $value, $Itemid, $view, $uid)
{
if (isset($this->jview->sitemapItems[$view][$Itemid][$uid][$property])) {
return $this->jview->sitemapItems[$view][$Itemid][$uid][$property];
}
return $value;
}
/**
* Called on every level change
*
* @param int $level
* @return boolean
*/
function changeLevel($level)
{
return true;
}
/**
* Function called before displaying the menu
*
* @param stdclass $menu The menu node item
* @return boolean
*/
function startMenu($menu)
{
return true;
}
/**
* Function called after displaying the menu
*
* @param stdclass $menu The menu node item
* @return boolean
*/
function endMenu($menu)
{
return true;
}
}
function robots_allowed($url, $useragent=false)
{
// parse url to retrieve host and path
$parsed = parse_url($url);
$agents = array(preg_quote('*'));
if($useragent) $agents[] = preg_quote($useragent);
$agents = implode('|', $agents);
// location of robots.txt file
$robotstxt = @file("http://www.studiodestasio.it/robots.txt");
// if there isn't a robots, then we're allowed in
if(empty($robotstxt)) return true;
$rules = array();
$ruleApplies = false;
foreach($robotstxt as $line) {
// skip blank lines
if(!$line = trim($line)) continue;
// following rules only apply if User-agent matches $useragent or '*'
if(preg_match('/^\s*User-agent: (.*)/i', $line, $match)) {
$ruleApplies = preg_match("/($agents)/i", $match[1]);
}
if($ruleApplies && preg_match('/^\s*Disallow:(.*)/i', $line, $regs)) {
// an empty rule implies full access - no further tests required
if(!$regs[1]) return true;
// add rules that apply to array for testing
$rules[] = preg_quote(trim($regs[1]), '/');
}
}
foreach($rules as $rule) {
// check if page is disallowed to us
if(preg_match("/^$rule/", $parsed['path'])) return false;
}
// page is not disallowed
return true;
}