Поддержка Плагины Поиск и замена кода, отдаваемого в браузер

  • Каждый раз, когда Я устанавливаю новую тему, Я удаляю из ней некоторые элементы, в которых не вижу смысла, руководствуясь принципом Бритвы Оккама. Ну, и иногда переставляю местами некоторые элементы, в общем — однозначно переход на другую тему сопровождается её модифицированием.
    Но когда-нибудь тема обновляется, из неё исчезают ошибки и добавляется функционал (добавляя новые 😀 ). И перед обновлением приходится переносить все внесенные изменения, вспоминая, что где поменял (ведь записывать всё это зачастую просто нереально).
    И вот, после нескольких событий и мыслей, Мне в голову пришла замечательная мысль. «А если есть плагин, который может искать и заменять куски кода? Ведь в таком случае при обновлении темы ничего переносить не придётся!» — подумал Я.
    И вот, поискав немного, нахожу плагин “Real-Time Find and Replace”. В его настройках всё просто: в поле слева вставляешь код, который нужно найти, а в поле справа вставляешь код, на который нужно заменить. Но в его описании написано следующее: «Set up find and replace rules that are executed AFTER a page is generated by WordPress, but BEFORE it is sent to a user’s browser.» Он вносит изменения в код ПОСЛЕ того, как WordPress генерирует страницу (т.е. исполняется PHP-код, который часто и хочется заменить), и ДО того, как страница отправляется в браузер. Получается, что заменить можно только сгенерированный HTML-код, который можно найти в исходном коде, отображаемом браузером.
    Вообще — прекрасный плагин, Я смог убрать некоторые ненужные мне элементы дизайна — например, список тэгов, которых можно использовать при оформлении комментария. Ведь у меня на сайте стоит плагин NicEdit (это WYSIWYG для комментов).
    Но вот что странно: одно правило по поиску и замене PHP-кода работает, иное — нет.
    Вот то, что работает:
    ищем

    <?php
    					// Check if this is a post or page, if it has a thumbnail, and if it's a big one
    					if ( is_singular() &&
    							has_post_thumbnail( $post->ID ) &&
    							( /* $src, $width, $height */ $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'post-thumbnail' ) ) &&
    							$image[1] >= HEADER_IMAGE_WIDTH ) :
    						// Houston, we have a new header image!
    						echo get_the_post_thumbnail( $post->ID, 'post-thumbnail' );
    					else : ?>
    						<img src="<?php header_image(); ?>" width="<?php echo HEADER_IMAGE_WIDTH; ?>" height="<?php echo HEADER_IMAGE_HEIGHT; ?>" alt="" />
    					<?php endif; ?>

    и заменяем на

    <img src="http://grawl.ru/other/randomheader/<?php echo(rand(1,24)); ?>.png"
     width="image_width" height="image_height" alt="image_alt_text" />

    Тем самым Я реализовал у себя на сайте динамическое изменение изображения в шапке сайта на одно из 24-х из коллекции, не меняя при этом код темы.
    А вот то, что не работает:
    ищем

    <?php twentyten_posted_in(); ?>
    						<?php edit_post_link( __( 'Edit', 'twentyten' ), '<span class="edit-link">', '</span>' ); ?>

    и заменяем на

    <?php twentyten_posted_on(); ?>
    						<?php edit_post_link( __( 'Edit', 'twentyten' ), '<span class="edit-link">', '</span>' ); ?>

    Это Я хотел заменить надпись «Запись опубликована в рубрике Без рубрики. Добавьте в закладки постоянную ссылку.» на дату публикации.
    Хотелось бы понять, почему так, ну или найти плагин, который смог бы вносить правки в код, который WordPress ещё не скомпилировал в чистый HTML.

    Надеюсь, достаточно точно дал название темы.

Просмотр 6 ответов — с 1 по 6 (всего 6)
  • Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    Я в подобных случаях с помощью утилиты diff делаю патч со своими правками, который после обновления применяю. Плюс: если патч не применился из-за отличий в новом коде, это видно сразу. Минус: неполная автоматизация. Впрочем, полная вряд ли возможна, поэтому иногда это тоже плюс 🙂

    Atrax

    (@atrax)

    Ethical engineer

    1. Странно, что первый вариант сработал.
    2. Вы создаете дополнительную нагрузку на сервер.
    Лучше — хотя и не легче — исправить прямо в исходном коде.

    Sergey Biryukov, расскажите подробнее, а то статья, на которую Вы дали ссылку, мне совершенно непонятна.
    Atrax, это троллинг?

    Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    Atrax говорит верно — я тоже удивился, что первая замена работает. Дополнительная нагрузка на сервер также имеет место.

    Путём некоторых ухищрений удалось заставить плагин понимать PHP-код. Нужно в этот фрагмент файла real-time-find-and-replace.php:

    foreach ($farsettings['farfind'] as $key => $find){
    	if(isset($farsettings['farregex'][$key]))
    		$buffer = preg_replace($find, $farsettings['farreplace'][$key], $buffer);
    	else
    		$buffer = str_replace($find, $farsettings['farreplace'][$key], $buffer);
    }

    добавить две строки:

    foreach ($farsettings['farfind'] as $key => $find){
    	$find = eval("?>$find<?php ");
    	$farsettings['farreplace'][$key] = eval("?>{$farsettings['farreplace'][$key]}<?php ");
    	if(isset($farsettings['farregex'][$key]))
    		$buffer = preg_replace($find, $farsettings['farreplace'][$key], $buffer);
    	else
    		$buffer = str_replace($find, $farsettings['farreplace'][$key], $buffer);
    }

    Однако и после этого мы не можем просто заменить twentyten_posted_in() на twentyten_posted_on(), потому что эти функции выводят информацию сразу на экран, а для замены нам нужно получить её в виде строки. Можно скопировать их с небольшими изменениями в окно поиска:

    <?php
    // Retrieves tag list of current post, separated by commas.
    $tag_list = get_the_tag_list( '', ', ' );
    if ( $tag_list ) {
    	$posted_in = __( 'This entry was posted in %1$s and tagged %2$s. Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>.', 'twentyten' );
    } elseif ( is_object_in_taxonomy( get_post_type(), 'category' ) ) {
    	$posted_in = __( 'This entry was posted in %1$s. Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>.', 'twentyten' );
    } else {
    	$posted_in = __( 'Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>.', 'twentyten' );
    }
    // Prints the string, replacing the placeholders.
    return sprintf(
    	$posted_in,
    	get_the_category_list( ', ' ),
    	$tag_list,
    	get_permalink(),
    	the_title_attribute( 'echo=0' )
    );
    ?>

    и в окно замены:

    <?php
    return sprintf( __( '<span class="%1$s">Posted on</span> %2$s <span class="meta-sep">by</span> %3$s', 'twentyten' ),
    	'meta-prep meta-prep-author',
    	sprintf( '<a href="%1$s" title="%2$s" rel="bookmark"><span class="entry-date">%3$s</span></a>',
    		get_permalink(),
    		esc_attr( get_the_time() ),
    		get_the_date()
    	),
    	sprintf( '<span class="author vcard"><a class="url fn n" href="%1$s" title="%2$s">%3$s</a></span>',
    		get_author_posts_url( get_the_author_meta( 'ID' ) ),
    		sprintf( esc_attr__( 'View all posts by %s', 'twentyten' ), get_the_author() ),
    		get_the_author()
    	)
    );
    ?>

    Теперь на моей установке замена происходит успешно.

    Спасибо большое! Сейчас буду разбираться.

    Так. Первая замена, оказывается, не работает: это всё Моя невнимательность. Простите.
    Насчёт нагрузки на сервер: да, Я понимаю, что это — немного дополнительных телодвижений серверу, но в размерах моего маленького блога, Я думаю, это не страшно, зато как эффективно!
    Троллингом Я назвал это:

    Лучше — хотя и не легче — исправить прямо в исходном коде.


    Кстати, рандомную картинку в заголовке Я только-что реализовал плагином «WP Random Header». Удивительно, всё уже придумано!

    У меня не сработало то правило, что Вы предложили, Sergey Biryukov, хотя Я всё сделал по Вашей инструкции.
    Хотя… Может, в чём-то и накосячил (всякое бывает). Чуть позже снова попробую.

    Хм, теперь и обычные правила не работают. Значит, чего-то в плагине накосячил.

Просмотр 6 ответов — с 1 по 6 (всего 6)
  • Тема «Поиск и замена кода, отдаваемого в браузер» закрыта для новых ответов.