Problema con preg_replace

Iniciado por PhenfiX, 10 Abril 2008, 20:47 PM

0 Miembros y 1 Visitante están viendo este tema.

PhenfiX

Hola a todos!

Esta vez tengo un problema que al parecer es de fácil solución, solo que no la encuentro  :¬¬

Resulta que tengo esta fracción de código:


    <td>
      <b>{tdownload}:</b> <a href="{url}">{name}</a> <small>({size})</small> <b>{tclicks}:</b> {clicks} <br />
      <b>{tadded}:</b> {date} <br />
      <b>{tclicks}:</b> {clicks}
    </td>


En un fichero TPL (el que es usado para los templates), y al mismo le quiero insertar un poco de PHP, pero me topo con este otro fragmento de código:


$content .= preg_replace('/\{([^}]*)}/e', '$row[\\1]', $dmTemplateContent);


Que se encuentra en un fichero PHP, y que mediante include se combinan.

El problema, obviamente, es que al insertar código PHP en el fichero TPL, este me es remplazado por otros caracteres.

Ejemplo, si inserto "if ($pos == false) { ?>" el simbolo "{" se cambia por otro.

Me gustaría saber como puedo hacer para insertar PHP en el TPL, ya sea que ignore el preg_replace o que use otros caracteres.

No se si me expliqué, pero creo que si :P

Gracias por adelantado.

eLank0

Hola,

Antes de nada quiero hacer una aclaración, en teoría los templates están hechos para que se separe el diseño del código, y por lo tanto no creo que sea una buena idea introducir código PHP en un archivo TPL.

Como lo que aparece en index.tpl depende del código del index.php, lo que podrías hacer es incluir en tu index.php un archivo con el código que quieras incluir.

Salu2

PhenfiX

Gracias por tu respuesta.

Me resulta bastante complicado explicarte por que no puedo hacerle como tú dices, ya lo intente de 4 formas, las 4 que se me ocurrieron.

Como propones: Genera conflicto en la linea antes mencionada.
Como yo decía: Modifica los {corchetes por otro símbolo.
Metiendo include no marca ni error ni funciona.

Si fueran simples páginas lo modificaría sin esfuerzo, el problema es que estoy hablando de un widget de Wordpress, y para hacerlo funcionar necesito meterle php antes y despues, y al hacerlo genera conflictos con un fuctions.php bastante complicado para mi entendimiento.

Lo que me interesa saber, y no he encontrado ni siquiera en php.net, es si puedo de alguna manera ignorar, o camuflar los corchetes anteponiendole otro símbolo.
Los corchetes son los que me causan problema.

Gracias

SirLanceCC

¿que quieres hacer?
reemplazar {clicks} {name} por variables???


NO Ya te entendí... quieres incrustar php en el archivo template pero como la función reemplaza los corchetes {} por variables... si en el archivo templete escribes "if(x) {" estas usando corchetes que serán reemplazados y no se ejecutará el código que deseas...


Tendrías que explicar más ampliamente cual es tu ibjetivo final y cómo lo estás realizando, para que pueda ayudarte...

PhenfiX

Pues si, es justamente eso.

Tengo 2 ficheros, un functios.php y un template.tpl, juntos trabajan bien, pero me resulta muy complicado añadir un trozo de PHP al TPL.

El TPL es esto:
<table cellpadding="3" width="100%" border="0">
  <tr>
    <td width="35" style="vertical-align: top;">
      <img src="{icon}" alt="{icon}">
    </td>
    <td>
      <b>{tdownload}:</b> <a href="{url}">{name}</a> <small>({size})</small> <b>{tclicks}:</b> {clicks} <br />
      <b>{tadded}:</b> {date} <br />
      <b>{tclicks}:</b> {clicks}
    </td>
  </tr>
  <tr>
    <td colspan="2">{description}</td>
  </tr>
</table>


Como verás no es nada complicado, solo que el functions remplaza los corchetes por variables. Esta línea lo hace:

$content .= preg_replace('/\{([^}]*)}/e', '$row[\\1]', $dmTemplateContent);

No puedo añadir PHP al TPL porque se remplazan. No puedo añadir PHP al functions por que es una página SOLO de funciones. No puedo añadir PHP al index porque marca error.
La única solución que se me ocurre es intentar, como ya lo había mencionado, camuflar los corchetes del PHP insertados en el TPL.

Ya le di dos repasadas a Google y no logro hacerlo.
Lo que también se podría hacer es añadir al functions otro simbolo, y este usarlo para que se convierta en corchete, solo que no se hacerlo :P

SirLanceCC

CitarNo puedo añadir PHP al TPL porque se remplazan. No puedo añadir PHP al functions por que es una página SOLO de funciones. No puedo añadir PHP al index porque marca error.
Bueno pero que quieres que haga tu modificacion?

CitarLo que también se podría hacer es añadir al functions otro simbolo, y este usarlo para que se convierta en corchete, solo que no se hacerlo
Lo que puedes hacer es que deje de reemplazar {variable}  y reemplace [variable] o {{variable}} o *variable*. Aunque como dijeron no se ve bonito mezclar los tpl con codigo, y no se si se ejecute.

$content .= preg_replace('/\{([^}]*)}/e', '$row[\\1]', $dmTemplateContent);
A ver intenta cambiar esas llaves por doble llave o corchete o lo que quieras... recuerda que en tpl debes cambiar tambien las llaves por el simbolo para que las reemplace.

PhenfiX

Mira, para que me entiendas posteo los códigos:

TPL:
<table cellpadding="3" width="100%" border="0">
  <tr>
    <td width="35" style="vertical-align: top;">
      <img src="{icon}" alt="{icon}">
    </td>
    <td>
      <b>{tdownload}:</b> <a href="{url}">{name}</a> <small>({size})</small> <b>{tclicks}:</b> {clicks} <br />
      <b>{tadded}:</b> {date} <br />
      <b>{tclicks}:</b> {clicks}
    </td>
  </tr>
  <tr>
    <td colspan="2">{description}</td>
  </tr>
</table>


Functions:

### Load Download Page Template
function DownloadsManager_DownloadsPage($content) {
  global $wpdb, $table_prefix, $iconsdir;
  if(!preg_match("|<!--download table-->|", $content))
    return $content;
  $start = strpos($content, '<!--download table-->');
  $before = substr($content, 0, $start);
  $after = substr($content, 21+$start);
  $dmTemplate = 'wp-content/plugins/downloads-manager/page-download-template.tpl';
  $handle = @fopen($dmTemplate, 'r');
  if(!$handle)
    return __('Error... Unable to load page template. Search page-download-template.tpl in your plugin folder!','downloads-manager');
  $dmTemplateContent = fread($handle, filesize($dmTemplate));
  $content = "";
  $cats = $wpdb->get_results("SELECT id, name FROM ".$table_prefix."dm_category");
  if(!empty($cats)) {
    foreach($cats as $cat) {
      $rows = $wpdb->get_results("SELECT d.id,d.name,d.link,d.icon,d.category,d.description,d.date,d.clicks FROM ".$table_prefix."dm_downloads d WHERE d.category='".$cat->id."'", ARRAY_A);
      if(!empty($rows)) {
        $content .= "<h2 style=\"border-bottom: 1px dotted #CCC\">".$cat->name."</h2>";
        foreach($rows as $row) {
          $row['icon'] = $iconsdir.'/'.$row['icon'];
          $row['date'] = date('d/m/Y', $row['date']);
          $row['size'] = FileSizeOf($row['link']);
          $row['url'] = dm_get_url_type($row['id']);
          $dmTemplateContent = preg_replace('/\{(t)([^}]*)}/e', __('\\2','downloads-manager'), $dmTemplateContent);
          $content .= preg_replace('/\{([^}]*)}/e', '$row[\\1]', $dmTemplateContent);
        }
      }
    }
  }
  fclose($handle);
  $content = $before.$content.$after;
  return $content;
}

?>


Y el código que quiero instertar:

<?php

$agent 
$_SERVER['HTTP_USER_AGENT'];
$pos strpos($agent"Firefox");

if (
$pos == false) { ?>


<div>
Texto si no está usando FF
</div>

<? }else{ ?>

AQUÍ DEBE IR EL TPL

<? } ?>


Como ves, el código del TPL va en medio del script, y resulta bastante difícil hacerlo de otra forma.
Es un widget de Wordpress, por lo que modificar el fuctions afectaría a otras areas.

Para llamar al script se debe poner en el post:
<!--download table-->
...y esto muestra la tabla. Si añado PHP al post marca error.

Como te digo, la única solución (sin tener que modificar todo el widget) es encontrar la manera de camuflar el php, o bien, como tu dices, darle otro valor al corchete, e ahí el problema.

SirLanceCC

#7
Yo lo haría algo asi

Código (php) [Seleccionar]
### Load Download Page Template
function DownloadsManager_DownloadsPage($content) {
  global $wpdb, $table_prefix, $iconsdir;
  if(!preg_match("|<!--download table-->|", $content))
    return $content;
  $start = strpos($content, '<!--download table-->');
  $before = substr($content, 0, $start);
  $after = substr($content, 21+$start);
  $dmTemplate = 'wp-content/plugins/downloads-manager/page-download-template.tpl';
  $handle = @fopen($dmTemplate, 'r');
  if(!$handle)
    return __('Error... Unable to load page template. Search page-download-template.tpl in your plugin folder!','downloads-manager');
  $dmTemplateContent = fread($handle, filesize($dmTemplate));
  $content = "";
  $cats = $wpdb->get_results("SELECT id, name FROM ".$table_prefix."dm_category");
  if(!empty($cats)) {
    foreach($cats as $cat) {
      $rows = $wpdb->get_results("SELECT d.id,d.name,d.link,d.icon,d.category,d.description,d.date,d.clicks FROM ".$table_prefix."dm_downloads d WHERE d.category='".$cat->id."'", ARRAY_A);
      if(!empty($rows)) {
        $content .= "<h2 style=\"border-bottom: 1px dotted #CCC\">".$cat->name."</h2>";
        foreach($rows as $row) {
          $row['icon'] = $iconsdir.'/'.$row['icon'];
          $row['date'] = date('d/m/Y', $row['date']);
          $row['size'] = FileSizeOf($row['link']);
          $row['url'] = dm_get_url_type($row['id']);

//Creamos una variable con el mensaje pertinente
          //Si no es firefox
          if(strpos($_SERVER['HTTP_USER_AGENT'], "Firefox") == false){
              $row['mensajeff'] = 'Usa FIREFOX pagano!';
          } else { //si es
              $row['mensajeff'] = ''; //nada
          }

//Estas lineas se encargarán de escribir nuestro mensaje
          $dmTemplateContent = preg_replace('/\{(t)([^}]*)}/e', __('\\2','downloads-manager'), $dmTemplateContent);
          $content .= preg_replace('/\{([^}]*)}/e', '$row[\\1]', $dmTemplateContent);
        }
      }
    }
  }
  fclose($handle);
  $content = $before.$content.$after;
  return $content;
}

?>


En el TPL sólo agregamos la variable {mensaje ff} donde quieras que aparaezca el mensaje

PhenfiX

Muchas gracias, ya lo probé y funciona. Solo que hay un problema, el TPL es condicional, osea que solo se muestra si están usando FF, no como un simple mensaje.

Me explico. Tengo una sección de descargas,  de plugins para FF, entonces si el usuario usa FF las muestra, si usa otro navegador le digo que son descargas exclusivas para FF.

¿En ese caso cómo sería?

Muchas gracias por tu ayuda

SirLanceCC

Mmmmm a veeeerrrr....
Código (php) [Seleccionar]
## Load Download Page Template
function DownloadsManager_DownloadsPage($content) {
//Antes que nada verificamos si es firefox
//Si no es firefox
  if(strpos($_SERVER['HTTP_USER_AGENT'], "Firefox") == false) return '';
  //devolvemos una cadena vacia para que sustituya a <!--download table--> supongo...
  //Y con eso finaliza la función... sin mostrar nada...
//pero si sí usamos firefox.. hace todo lo de aqui abajo y muestra lo que tiene que mostrar...

  global $wpdb, $table_prefix, $iconsdir;
  if(!preg_match("|<!--download table-->|", $content))
    return $content;
  $start = strpos($content, '<!--download table-->');
  $before = substr($content, 0, $start);
  $after = substr($content, 21+$start);
  $dmTemplate = 'wp-content/plugins/downloads-manager/page-download-template.tpl';
  $handle = @fopen($dmTemplate, 'r');
  if(!$handle)
    return __('Error... Unable to load page template. Search page-download-template.tpl in your plugin folder!','downloads-manager');
  $dmTemplateContent = fread($handle, filesize($dmTemplate));
  $content = "";
  $cats = $wpdb->get_results("SELECT id, name FROM ".$table_prefix."dm_category");
  if(!empty($cats)) {
    foreach($cats as $cat) {
      $rows = $wpdb->get_results("SELECT d.id,d.name,d.link,d.icon,d.category,d.description,d.date,d.clicks FROM ".$table_prefix."dm_downloads d WHERE d.category='".$cat->id."'", ARRAY_A);
      if(!empty($rows)) {
        $content .= "<h2 style=\"border-bottom: 1px dotted #CCC\">".$cat->name."</h2>";
        foreach($rows as $row) {
          $row['icon'] = $iconsdir.'/'.$row['icon'];
          $row['date'] = date('d/m/Y', $row['date']);
          $row['size'] = FileSizeOf($row['link']);
          $row['url'] = dm_get_url_type($row['id']);
          $dmTemplateContent = preg_replace('/\{(t)([^}]*)}/e', __('\\2','downloads-manager'), $dmTemplateContent);
          $content .= preg_replace('/\{([^}]*)}/e', '$row[\\1]', $dmTemplateContent);
        }
      }
    }
  }
  fclose($handle);
  $content = $before.$content.$after;
  return $content;
}


A ver si mi planteamiento es correcto y te funciona...