2009-12-24 17 views
11

Quiero poder tomar el texto ingresado por el usuario en un campo de comentario y verificar la expresión del tipo de URL, y si existe, agregar una etiqueta de anclaje (a url) cuando se muestra el comentario.Cómo agregar una etiqueta de anclaje a una URL de la entrada de texto

Estoy usando PHP en el lado del servidor y Javascript (con jQuery) en el cliente, así que ¿debo esperar a buscar la URL hasta justo antes de que se muestre? ¿O agregar la etiqueta de anclaje antes de insertarla en la base de datos?

por lo

<textarea id="comment">check out blahblah.com or www.thisthing.co.uk or http://checkthis.us/</textarea> 

convierte

<div id="commentDisplay">check out <a href="blahblah.com">blahblah.com</a> or <a href="www.thisthing.co.uk">www.thisthing.co.uk</a> or <a href="http://checkthis.us/">http://checkthis.us/</a></div> 
+3

entiendo lo que estás tratando de lograr, pero como su ejemplo es sintácticamente inválido, simplemente lo advertiría: debe especificar las URL externas con un ** protocolo ** (http: //); de lo contrario, se volverán relativas y apuntarán a su propio dominio. Por lo tanto, 'http: // blahblah.com' y así sucesivamente. – BalusC

+1

Si realiza ese tipo de manipulación antes de insertar el comentario en la base de datos, tendrá un problema si alguien quiere editar su publicación: habrá algo de HTML en el medio ;; entonces, o bien haga esa manipulación al mostrar, o almacene 2 versiones del comentario en el DB (una "limpia", y una "transformada/enriquecida") –

+0

@BalusC tiene razón, quise cambiar eso en la pantalla, pero Conseguí copiar y pegar feliz y olvidé. – Douglas

Respuesta

22

En primer lugar, una petición. No hagas esto antes de escribir los datos en la base de datos. En cambio, hazlo antes de mostrar los datos al usuario final. Esto reducirá toda confusión y te permitirá más flexibilidad en el futuro.

Un ejemplo found online siguiente:

$text = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)?)@', '<a href="$1">$1</a>', $text); 

Y una mucho más completa de daringfireball.net:

/** 
* Replace links in text with html links 
* 
* @param string $text 
* @return string 
*/ 
function auto_link_text($text) 
{ 
    $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#'; 
    $callback = create_function('$matches', ' 
     $url  = array_shift($matches); 
     $url_parts = parse_url($url); 

     $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH); 
     $text = preg_replace("/^www./", "", $text); 

     $last = -(strlen(strrchr($text, "/"))) + 1; 
     if ($last < 0) { 
      $text = substr($text, 0, $last) . "&hellip;"; 
     } 

     return sprintf(\'<a rel="nowfollow" href="%s">%s</a>\', $url, $text); 
    '); 

    return preg_replace_callback($pattern, $callback, $text); 
} 
+0

esto funcionaría, aunque tengo miedo de un posible retraso (se mostrarán muchos comentarios a la vez) – Douglas

+0

Dale una oportunidad. Dudo que experimentes un retraso notable. – Sampson

+0

eso es realmente bueno (segunda función) –

2

Personalmente, marcarlo con JS justo antes de mostrar, parece más profesional y sostenible que editar el comentario del usuario por ti mismo.

1

Preferiría hacer eso en el lado del servidor. Javascript tiene un "retraso"; se ejecuta solo cuando todo el árbol DOM HTML se ha cargado y se muestra en el navegador web. Por lo tanto, puede tomar una (aunque breve) mientras que antes de que las URL sean reconocidas y analizadas. El cliente puede ver los enlaces instantáneamente reemplazados mientras todavía enfrenta el contenido. Esto podría llevar a "wtf?" experiencias en el lado del cliente. Esto hoy en día está relacionado demasiado rápidamente con advertisting/spam/spyware. Deberías evitar eso tanto como sea posible. No use JS para cambiar el contenido cargado, sino solo durante los eventos controlados por el usuario (onclick, onchange, onfocus, etc.). Use el idioma del lado del servidor para cambiar el contenido antes de guardarlo o mostrarlo.

Así que solo busque un script PHP que analice el texto (o use expresiones regulares) para construir enlaces completos basados ​​en URLs en texto sin formato. Puede encontrar mucho here. Buena suerte.

+0

estoy de acuerdo con la declaración WTF y el retraso, aunque podría tener que ajustar la columna DB que contiene el comentario para tener más caracteres para tener en cuenta los que se agregaron en el PHP – Douglas

13

He adaptado la opción de expresiones regulares de Jonathan Sampson para que sea más indulgente sobre lo que es un dominio (no necesita http (s) para calificar).

function hyperlinksAnchored($text) { 
    return preg_replace('@(http)?(s)?(://)?(([-\w]+\.)+([^\s]+)+[^,.\s])@', '<a href="http$2://$4">$1$2$3$4</a>', $text); 
} 

Obras para estas URL (y con éxito deja fuera a punto o una coma final):

http://www.google.com/ 
https://www.google.com/. 
www.google.com 
www.google.com. 
www.google.com/test 
google.com 
google.com, 
google.com/test 
123.com/test 
www.123.com.au 
ex-ample.com 
http://ex-ample.com 
http://ex-ample.com/test-url_chars.php?param1=val1. 
http://ex-ample.com/test-url_chars?param1=value1&param2=val+with%20spaces 

la esperanza de que ayude a alguien.

+1

He estado buscando una respuesta en todas partes que funciona para todos los casos diferentes que se muestran en su ejemplo.¡Gracias por tomarse el tiempo de compartir esto con la comunidad! ¡Gran trabajo! – zeckdude

+1

Esto no funcionará si el URL comienza con 's' ex: something.com – user1846348

+1

@ user1846348 es correcto. Tampoco funcionará para un dominio como httpfun.com – Dex

2

respuesta de Refinación Markd para evitar enlaces en decimales, porcentajes, fechas numéricas (10.3.2001), elipsis y las direcciones IP:

function addLinks($text) { 
    return preg_replace('@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@', '<a target="ref" href="http$2://$4">$1$2$3$4</a>', $text); 
} 

Obras para:

http: // www.google .com/
https: // www.google.com /.
www.google.com
www.google.com.
www.google.com/test
google.com
google.com,
google.com/test
www.123.com.au
ex -ample.com
http: // ex-ample.com
http: // ex-ample.com/test-url_chars.php?param1=val1.
http: // ex-ample.com/test-url_chars?param1=value1 & param2 = val + con% 20spaces

no funciona para:

123.com/test (dominios numéricos sin ' www ")
Sigue así de prensa de la opinión popular ........ mantener el promedio (puntos suspensivos)
aumento de 3,8% 3,94 millones de 3,79 millones de (porcentajes y decimales)
Edited por Andrew Brooke - 08.07.2013 19:57 (fechas) dd.mm.yyyy
10.1.1.1 (direcciones IP)

Cuestiones relacionadas