Filtrowanie zawartości wpisu Wordpresa przed zapisem z htmLawed

.

W jednym z poprzednich wpisów przedstawiłem jak można wykorzystać funkcje filtra Kses do filtrowania zawartości w Wordpresie.
Filtr Kses jest dobry ale nie doskonały. Niezłą alternatywą (lub wsparciem) może być htmLawed.
W niniejszym wpisie przedstawię jak w łatwy sposób wykorzystać htmLawed do dodatkowego filtrowania zawartości wpisu, tytułu i wypis przed ich zapisem do bazy danych. Funkcjonalność z łatwością można przenieść na niemal każde dane wejściowe i wyjściowe (np. komentarze).

HtmLawed to filtr, który został napisany na potrzeby LabWiki i jest dostępny na licencji LGPL v3.
Cała funkcjonalność jaką biblioteka oferuje zawarta jest w jednym pliku, co dodatkowo ułatwia użycie jej w Wordpresie.
Paczkę z filtrem można ściągnąć z tej strony.

Na potrzeby tego wpisu stworzyłem przykładową wtyczkę o nazwie ws_html_lawed, której struktura wygląda jak następuje:


sw_html_lawed/
  sw_html_lawed.php
  lib/
    htmLawed.php

Wtyczka ma za zadanie przefiltrować zawartość wpisu, jego tytuł oraz wypis przed zapisem tych danych do tabeli bazy danych.
Cały kod mojej wtyczki znajduje się w pliku sw_html_lawed.php i wygląda jak następuje:


/*
Plugin Name: sw_html_lawed
Plugin URI: n/a
Description: Przykładowa wtyczka wykorzystając filtr HtmLawed
Author: S.Wojnowski
Version: 0.0.1
Author URI: http://wojnowski.net.pl
*/

require(WP_PLUGIN_DIR.'/sw_html_lawed/lib/htmLawed.php');
$htm_lawed_config = array(
  'balance' => 1,
  'cdata' => 1,
  'clean_ms_char' => 1,
  'comments' => 1,
  'deny_attribute' => 'on',
  'keep_bad' =>  1,
  'lc_std_val' => 1,
  'safe' => 1,
  'tidy' => 1
);

$htm_lawed_spec = '';

function clean_content_with_htm_lawed($the_content){
  if(!current_user_can('unfiltered_html')){
    global $htm_lawed_config,$htm_lawed_spec;
    $the_content = htmLawed($the_content,$htm_lawed_config,$htm_lawed_spec);
    $to_be_removed = array( "#<p[^>]*>\s?</p>#", "#<a[^>]*>\s?</a>#", "#<font[^>]*>#", "#<\/font>#", "#<span[^>]*>\s?</span>#" );
    $the_content = preg_replace( $to_be_removed, '' , $the_content);
    return $the_content;
  }else{
    return $the_content;
  }
}
add_filter('content_save_pre', 'clean_content_with_htm_lawed');
add_filter('excerpt_save_pre', 'clean_content_with_htm_lawed');
add_filter('title_save_pre', 'clean_content_with_htm_lawed');

Filtr htmLawed, korzysta z konfiguracji ( w przypadku mojej wtyczki konfiguracja jest w tablicy $htm_lawed_config ), możliwe jest również określenie, które z atrybutów tagów HTML będą dozwolone a które powinny być usunięte ( $htm_lawed_spec ).
Pełną dokumentację mówiącą o tym, jak skonfigurować htmLawed można znaleźć na tej stronie.

Cały filtrujący kod wtyczki znajduje się w funkcji clean_content_with_htm_lawed. Filtr ma za zadanie filtrować zawartość każdego użytkownika za wyjątkiem administratora. Dodatkowo z zawartości usunięte zostaną puste tagi (p,a,font i span).

Funkcję clean_content_with_htm_lawed podłączyłem do kilku filtrów, tj. content_save_pre, excerpt_save_pre, title_save_pre.

W przypadku mojej wtyczki, każda część danych wpisu jest filtrowana za pośrednictwem tej samej funkcji co niekoniecznie jest dobrym pomysłem.
Aby to zmienić wystaczy dopisać dodatkową funkcję filtrującą i podłączyć ją pod odpowiedni filtr ( np. title_pre_save ).

Można również określić kiedy ma być przefiltrowana zawartość określając trzeci parametr do funkcji add_filter. Domyślnie htmlLawed jest uruchamiany po funcjach Ksesa, aby to zmienić, trzeci parametr dla add_filter powinien miec wartość mniejszą niż 10.

Kses w Wordpresie może być całkowicie zastąpiony przez htmlLawed (informacje jak tego dokonać można znaleźć na tu), wymaga to jednak pewnych modyfikacji plików silnika, czego nie zalecam ze względu na trudności z aktualizacją systemu do nowszych wersji.

Funkcje Ksesa dla zapisu zawartości, tytułu i wypisu wpisu można łatwo wyłączyć, efektywnie zastępując część oferowanej przez tą bibliotekę funkcjonalności to z htmLawed:


remove_filter('title_save_pre', 'wp_filter_kses');
remove_filter('content_save_pre', 'wp_filter_post_kses');
remove_filter('excerpt_save_pre', 'wp_filter_post_kses');

Każda manipulacja ustawieniami Ksesa może mieć wpływ na bezpieczeństwo bloga, stąd istotne jest aby zrozumieć i poprawnie skonfigurować htmLawed.
Wydaje mi się, że najlepszym rozwiązaniem jest zastosowanie podwójnego filtra w przypadkach wymagających ponadstandardowych zabezpieczeń.

HtmLawed nie jest jedyną biblioteką, którą można zastąpić lub wspomóc Ksesa. Inną ciekawą alternatywą może być choćby HTMLTidy.

Kod wtyczki sw_html_lawed można sobie pobrać stąd. Aby ją aktywować należy rozpakować plik .zip i uruchomić i wykonać standardową procedurę w panelu administracyjnym Wordpresa.


Twój komentarz





Niektóre tagi XHTML są dozwolone
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>