Рубрика: Верстка / Front-end

Вывод комментариев в WordPress с ответами

Для того, чтобы вывести все комментарии сайта (а не только для текущей страницы), мы разработали такой код:

<?php $comments = get_comments([
			'status' => 'approve', // Только одобренные комментарии
			'orderby' => 'comment_date_gmt', // Сортировка по дате
			'order' => 'DESC', // Порядок вывода: старые сначала
		]);?>
		<?php 
		// Группируем комментарии по их родителям
		$grouped_comments = group_comments_by_parent($comments);
		
		// Выводим комментарии
		if (!empty($comments)) {
			render_all_comments($comments, $grouped_comments);
		} else {
			echo '<p>' . __('No comments found.') . '</p>';
		}
		?>

// Функция для группировки комментариев по родителю
function group_comments_by_parent($comments) {
	$grouped = array();

	foreach ($comments as $comment) {
		$parent_id = $comment->comment_parent;
		if (!isset($grouped[$parent_id])) {
			$grouped[$parent_id] = array();
		}
		$grouped[$parent_id][] = $comment;
	}

	return $grouped;
}

// Функция для рекурсивного отображения комментариев
function render_all_comments($comments, $grouped, $parent_id = 0, $depth = 0) {
	if (isset($grouped[$parent_id])) {

		foreach ($grouped[$parent_id] as $comment):?>
		<article class="comment <?php if($comment->comment_parent):?>reply<?php endif;?>" id="<?php echo $comment->comment_ID;?>">
			<header class="author-data">
				<?php $date = new DateTime($comment->comment_date);?>
				<address class="author" rel="author"><?php echo $comment->comment_author;?></address>
				<time pubdate datetime="<?php echo $date->format('Y-m-d');?>" title="<?php echo $date->format('F d Y');?>"><?php echo $date->format('h:m:s');?> <span><?php echo $date->format('d.m.Y');?></span></time>
			</header>
			<div class="comment-content"><?php echo $comment->comment_content;?></div>
		</article>
		<?php
			// Рекурсивно отображаем ответы на текущий комментарий
			render_all_comments($comments, $grouped, $comment->comment_ID, $depth + 1);
		?>
		<?php endforeach;?>
	<?php }
}

Получение комментариев

<?php $comments = get_comments([
    'status' => 'approve', 
    'orderby' => 'comment_date_gmt',
    'order' => 'DESC',
]);?>

Функция get_comments получает комментарии:

  • status: только одобренные.
  • orderby: сортируются по дате.
  • order: выводятся в обратном порядке (сначала новые).

Группировка комментариев

$grouped_comments = group_comments_by_parent($comments);

Функция group_comments_by_parent распределяет комментарии по родителям. Это нужно для отображения иерархии (комментарий-ответ).

function group_comments_by_parent($comments) {
    $grouped = array();

    foreach ($comments as $comment) {
        $parent_id = $comment->comment_parent; // ID родительского комментария
        if (!isset($grouped[$parent_id])) {
            $grouped[$parent_id] = array(); // Создаем массив для родителя, если его еще нет
        }
        $grouped[$parent_id][] = $comment; // Добавляем комментарий в группу
    }

    return $grouped;
}

Отображение комментариев

if (!empty($comments)) {
    render_all_comments($comments, $grouped_comments);
} else {
    echo '<p>' . __('No comments found.') . '</p>';
}

Если есть комментарии, вызывается функция render_all_comments для их отображения.

Функция render_all_comments

function render_all_comments($comments, $grouped, $parent_id = 0, $depth = 0) {
    if (isset($grouped[$parent_id])) {
        foreach ($grouped[$parent_id] as $comment):?>
        <article class="comment <?php if($comment->comment_parent):?>reply<?php endif;?>" id="<?php echo $comment->comment_ID;?>">
            <header class="author-data">
                <?php $date = new DateTime($comment->comment_date);?>
                <address class="author" rel="author"><?php echo $comment->comment_author;?></address>
                <time pubdate datetime="<?php echo $date->format('Y-m-d');?>" title="<?php echo $date->format('F d Y');?>"><?php echo $date->format('h:m:s');?> <span><?php echo $date->format('d.m.Y');?></span></time>
            </header>
            <div class="comment-content"><?php echo $comment->comment_content;?></div>
        </article>
        <?php
            render_all_comments($comments, $grouped, $comment->comment_ID, $depth + 1);
        ?>
        <?php endforeach;?>
    <?php }
}

Эта функция:

  1. Рекурсивно отображает комментарии: сначала выводит корневые, затем вложенные.
  2. Выводит данные комментария:
    • Автор: <?php echo $comment->comment_author;?>.
    • Дата и время: <?php $date->format(); ?>.
    • Текст комментария: <?php echo $comment->comment_content;?>.
  3. Рекурсивно вызывает себя для вложенных комментариев, передавая ID текущего комментария как parent_id.

Резюме

  1. Модулярность: Код хорошо структурирован с использованием функций (group_comments_by_parent и render_all_comments).
  2. Поддержка вложенности: Рекурсия позволяет отображать вложенные комментарии.
  3. Адаптируемость: Можно легко изменить структуру и оформление вывода, редактируя render_all_comments.

Этот шаблон подходит для страниц, где нужно отображать отзывы или комментарии с возможностью ответа.

Валидация ввода украинских и русских символов в jQuery

Иногда требуется ограничить ввод символов в текстовое поле так, чтобы пользователь мог вводить только буквы украинского и русского алфавитов. Это может быть полезно, например, для форм с именами и фамилиями, где нежелательны цифры, латинские символы или специальные знаки. Давайте рассмотрим, как с помощью jQuery можно легко реализовать такую валидацию.

Основная идея

С помощью метода .keyup() мы можем отслеживать события, происходящие при каждом нажатии клавиши в целевом поле ввода. Это позволит контролировать и корректировать содержимое поля в реальном времени. Для удаления недопустимых символов мы будем использовать регулярное выражение, которое оставит в поле только буквы кириллицы, включая специфические для украинского и русского алфавитов.

Код валидации

Для реализации валидации создайте следующий скрипт на JavaScript с использованием jQuery:

$("input#billing-first_name, input#billing-last_name").keyup(function() {
    $(this).val($(this).val().replace(/[^а-яА-ЯїЇєЄіІёЁ ]/g, ""));
});

Объяснение работы кода

  1. Выбор полей: В данном примере мы выбираем два поля с идентификаторами billing-first_name и billing-last_name. Это могут быть, например, поля для ввода имени и фамилии в форме.
  2. Отслеживание ввода: Используя метод .keyup(), мы подключаем функцию, которая будет выполняться каждый раз, когда пользователь отпускает клавишу. Это позволяет применять валидацию по мере ввода текста.
  3. Замена символов: Метод .replace() используется для замены всех неподходящих символов на пустую строку. Регулярное выражение /[^а-яА-ЯїЇєЄіІёЁ ]/g определяет:
    • ^ — отрицание, т.е. все символы, не соответствующие выражению;
    • а-яА-Я — русские буквы (и в нижнем, и в верхнем регистре);
    • їЇєЄіІ — буквы, уникальные для украинского языка;
    • ёЁ — буква «ё» в русском алфавите;
    • — пробел (для удобства, если нужно вводить фамилию, состоящую из двух частей).
    Всё, что не попадает под эти символы, будет заменено на пустую строку, т.е. удалено из поля.

Применение и возможные изменения

Такой код можно легко адаптировать для других полей или расширить список символов, если необходимо. Например, если вы хотите, чтобы поля принимали и латинские буквы, можно добавить их в регулярное выражение. Вот пример для кириллицы и латиницы:

$("input#billing-first_name, input#billing-last_name").keyup(function() {
    $(this).val($(this).val().replace(/[^а-яА-ЯїЇєЄіІёЁa-zA-Z ]/g, ""));
});

Преимущества и ограничения метода

Преимущества:

  • Простота и лёгкость внедрения. Несколько строк кода обеспечивают базовую валидацию.
  • Валидация происходит на стороне клиента, что улучшает UX (пользовательский опыт), так как пользователь сразу видит результат.

Ограничения:

  • Клиентская валидация уязвима, так как её можно обойти при отключённом JavaScript. Поэтому, если важна надёжность, следует продублировать валидацию и на сервере.
  • Скрипт работает только при наличии jQuery, поэтому нужно убедиться, что он подключен к проекту.

Заключение

Использование jQuery для валидации полей ввода на основе символов кириллицы — это простой и эффективный способ ограничить ввод только нужными символами. Благодаря регулярным выражениям и событиям jQuery вы можете гибко адаптировать проверку для самых разных форм и языков.

Как написать идеальный запрос (промпт) для ChatGPT

Сегодня в интернете можно найти множество рекомендаций по тому, как составить идеальный запрос (промпт) для ChatGPT. С развитием нейросетей такие инструменты стали важной частью как профессиональной, так и повседневной жизни. Ключевой навык — это умение правильно формулировать запросы, так как от этого зависит качество полученного ответа. Это актуально не только для ChatGPT, но и для других моделей, таких как ЯндексGPT или Google Bard. Чем точнее сформулирован запрос, тем более релевантный и точный ответ можно ожидать.

Что такое ChatGPT

ChatGPT — это чат-бот, разработанный компанией OpenAI, который обладает возможностью вести диалог, создавать шутки, стихи, статьи, резюме научных работ, а также писать программный код. Некоторые даже считают, что такие системы могут заменить людей в ряде профессий.

Почему ChatGPT популярен

Популярность ChatGPT обусловлена несколькими важными факторами:

  1. Обширная база данных: Модель обучена на большом объёме данных, что позволяет ей охватывать множество тем и давать разнообразные ответы.
  2. Доступность на разных платформах: ChatGPT легко интегрируется в различные приложения и интерфейсы, что делает его доступным для использования в различных сценариях.
  3. Точность ответов: Модель спроектирована с акцентом на предоставление корректных и полезных ответов, избегая сложных или спорных тем.
  4. Постоянные улучшения: OpenAI активно развивает модель, добавляя новые функции и улучшая её точность, что позволяет ChatGPT оставаться лидером на рынке.
  5. Широкий спектр задач: Модель может решать различные задачи, такие как генерация текста, перевод, программирование, анализ данных и многое другое.
  6. Активное сообщество пользователей: Благодаря большому количеству пользователей и разработчиков, которые активно используют ChatGPT, модель продолжает совершенствоваться.

Как составить идеальный запрос для ChatGPT

Чтобы получить качественный результат, при формулировании запроса стоит учесть несколько моментов:

  1. Роль: Определите, кем является ChatGPT в вашем запросе: журналистом, кулинаром, программистом и т. д. Это позволит модели адаптировать ответ, исходя из специфики выбранной роли.
  2. Задача: Сформулируйте задачу чётко и конкретно. Например: «Составь план питания для мужчины 25 лет с весом 70 кг, работающего в офисе».
  3. Цель: Определите, для кого предназначен ответ, например: «Напиши короткий пост для предпринимателей в VK». Это поможет получить ответ, соответствующий вашей целевой аудитории.
  4. Формат ответа: Укажите, в каком формате нужен ответ — рассказ, стихотворение, обзор или таблица. Можно также уточнить длину ответа, например, 300–500 слов.
  5. Контекст: Уточните детали, если требуется. ChatGPT сохраняет историю диалога, поэтому можно добавлять дополнительные условия без необходимости переписывать запрос целиком.

Полезные советы для работы с ChatGPT

  1. Дробите запросы: Для сложных задач, таких как решение математических уравнений, лучше разделить запрос на несколько этапов. Например, запросите вывод каждого шага по отдельности.
  2. Проверка ответа: Чтобы убедиться в точности ответа, можно попросить модель уточнить свою уверенность. Если ответ сомнительный, попробуйте изменить или уточнить запрос.
  3. Используйте примеры: Для более точного результата можно предоставить ChatGPT примеры текста или изображений, чтобы он мог на их основе создать собственный контент.

Заключение

Научиться правильно формулировать запросы для ChatGPT можно с помощью практики. Экспериментируйте, уточняйте и проверяйте результаты, чтобы добиться наилучшего качества ответов.

Полезные запросы к ChatGPT для программистов

Среди них: объяснение сложных алгоритмов, оптимизация кода, рефакторинг, генерация кода для задач и регулярных выражений, помощь в проектировании базы данных, архитектуре приложений, создании документации и CI/CD pipeline. ChatGPT также может предложить примеры использования библиотек и языков, помочь автоматизировать рутинные задачи и улучшить продуктивность программиста.

Многие опасаются, что нейросети, такие как ChatGPT, смогут заменить программистов. ChatGPT действительно умеет генерировать код, решать задачи и помогать в различных областях, однако в ближайшее время полностью заменить разработчиков она вряд ли сможет. Вместо этого нейросеть значительно ускоряет и облегчает их работу. Ключевую роль здесь играет правильный промтинг — умение формулировать запросы к ИИ так, чтобы получить нужный результат. Это отличается от привычных поисковых запросов, поскольку требует другого подхода к взаимодействию с ИИ.

Запросы для кода и алгоритмов

Эффективность и качество кода — ключевые аспекты работы программистов. Чтобы достичь высокого уровня, разработчики могут использовать нейросети для быстрого поиска решений. Промты в этом разделе помогут генерировать чистый и оптимизированный код, улучшать алгоритмы и повышать качество программного обеспечения.

Важно учитывать, что для разных задач запросы должны быть уникальными, будь то поиск ошибки или написание email. Конкретизация и контекст играют ключевую роль в получении качественного результата.

Пример промтов:

1. Объяснение сложного алгоритма

Пример запроса: «Объясни алгоритм Дейкстры пошагово».

ChatGPT не только объяснит, как работает алгоритм Дейкстры для поиска кратчайшего пути на графе, но и приведет конкретный пример с вершинами. Это поможет лучше понять, как алгоритм применяется на практике, и визуализировать его работу в контексте реальных данных.

2. Оптимизация кода

Пример запроса: «Оптимизируй этот Python-код для повышения производительности».

Допустим, у нас есть код, вычисляющий сумму квадратов чисел от 1 до nnn:

def sum_of_squares(n):
result = 0
for i in range(1, n + 1):
result += i * i
return result

n = 1000000
print(sum_of_squares(n))

ChatGPT может предложить улучшение, используя встроенную функцию sum и генератор:

def sum_of_squares(n):
    return sum(i * i for i in range(1, n + 1))

n = 1000000
print(sum_of_squares(n))

Этот подход повышает читаемость и производительность.

Промт 3: Генерация кода для конкретной задачи

Пример запроса: «Создай функцию на JavaScript для сортировки массива объектов по ключу».

ChatGPT может предложить такую функцию:

function sortByKey(array, key) {
    return array.sort((a, b) => {
        if (a[key] < b[key]) return -1;
        if (a[key] > b[key]) return 1;
        return 0;
    });
}

Эта функция сортирует объекты по указанному ключу. Вы также получите пример использования кода для практической задачи, что делает его удобным для немедленного применения.

Маркер на карте гугл с произвольной ссылкой

Для одного из проектов у нас потребовалось сделать на нашей карте клик по маркеру, чтобы открывалась необходимая ссылка. В нашем случае ссылка вела на открытие самих Google Maps и прокладывание маршрута от текущего места до офиса клиента.

var myLatlng = new google.maps.LatLng(50.5342832,30.2296718);
	var myOptions = {
		zoom:15,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		center: myLatlng,
		panControl: false,
		zoomControl: true,
		mapTypeControl: false,
		scaleControl: true,
		streetViewControl: false,
		overviewMapControl: false,
		disableDoubleClickZoom:true,
		suppressInfoWindows:true,
		scrollwheel: true
	};
	map = new google.maps.Map(document.getElementById("map"), myOptions);
	map.setOptions({styles: styles});
	
	var markerLatlng = new google.maps.LatLng(50.53248143295204, 30.229685611563006);
	const image = "/assets/images/pin.png";
	var marker = new google.maps.Marker({
		url: 'https://www.google.com/maps/dir//адрес клиента',
		position: markerLatlng,
		icon: image
	});

	marker.setMap(map);
	google.maps.event.addListener(marker, 'click', function() {
		window.open(marker.url, '_blank');
	});

В этом коде мы формируем карту с заданным центром и на ней размещаем необходимый нам маркер, который выглядит как пин (наше изображение, которое мы хотим разместить на карте). После этого мы для маркера указываем необходимую нам ссылку в параметре url.

var markerLatlng = new google.maps.LatLng(50.53248143295204, 30.229685611563006);
	const image = "/assets/images/pin.png";
	var marker = new google.maps.Marker({
		url: 'https://www.google.com/maps/dir//адрес клиента',
		position: markerLatlng,
		icon: image
	});

Далее вешаем обработчик клика по маркеру и открываем нашу ссылку. Мы захотели ее открыть в новом окне, используя параметр _blank.

google.maps.event.addListener(marker, 'click', function() {
		window.open(marker.url, '_blank');
	});

Какие CMS популярны? Как выбрать CMS при разработке сайта?

Выбор системы управления содержанием (CMS) для разработки сайта зависит от множества факторов, включая тип сайта, его функциональные требования, уровень сложности, потребности в масштабировании, удобство использования для администраторов, доступность расширений и т. д. Вот некоторые основные критерии, которые стоит учитывать при выборе CMS:

  1. Тип сайта: Важно определить, для чего будет использоваться сайт. Это может быть блог, интернет-магазин, корпоративный сайт, портфолио и т. д.
  2. Удобство использования: CMS должна быть интуитивно понятной для администраторов, чтобы они могли легко добавлять, редактировать и удалять контент.
  3. Безопасность: CMS должна обеспечивать надежную защиту от хакерских атак и иметь регулярные обновления безопасности.
  4. Экосистема плагинов и тем: Важно, чтобы CMS имела богатую экосистему дополнений, которые могут добавить необходимый функционал без необходимости в разработке с нуля.
  5. Сообщество и поддержка: Чем больше сообщество вокруг CMS, тем больше вероятность получения помощи и решения проблем.
  6. Скорость и производительность: CMS должна обеспечивать хорошую производительность сайта даже при высоких нагрузках.
  7. Расширяемость и масштабируемость: CMS должна позволять легко масштабировать сайт с ростом бизнеса.
  8. Стоимость: Некоторые CMS бесплатны, в то время как другие могут требовать лицензионные платежи или плату за дополнительный функционал.

Популярные CMS в мире:

  1. WordPress: Одна из самых популярных и распространённых CMS. Имеет большое сообщество пользователей и разработчиков, богатую библиотеку плагинов и тем.
  2. Joomla: Еще одна из популярных CMS, более подходящая для создания корпоративных сайтов и онлайн-журналов.
  3. Drupal: Мощная CMS, которая обладает расширенными возможностями по управлению контентом и поддерживает создание сложных сайтов.
  4. Magento: Специализированная CMS для интернет-магазинов, обладает широкими возможностями по управлению товарами, заказами и платежами.
  5. Shopify: Еще одна CMS, специализированная на интернет-магазинах, но отличается от Magento тем, что предлагает готовые решения в облаке, что облегчает настройку и управление.

В СНГ популярность могут иметь те же системы, но также стоит обратить внимание на локальные CMS, которые могут быть более адаптированы к специфике регионального рынка.

Замена вариаций продукта с Select на Radio buttons для WooCommerce (вариант 2)

В одном из статей был описан метод, как можно заменить стандарный вывод выбора вариаций с помощью select на radio. Эта статья находится тут.

Сегодня же будет показан еще один, альтернативный, вариант решения данной проблемы.

Открываем файл /ваша_тема/woocommerce/single-product/add-to-cart/variable.php (если такого файла нет, то нужно создать его.

В папке /ваша_тема/woocommerce/ находятся шаблоны woocommerce, которые изменяются для темы. Исходники их находятся в папке с плагином woocommerce в папке /templates.

В этом файле мы перед функцией вывода select выбора вариаций товара добавляем

<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>

и оборачиваем все это (вместе с выводом select) в обертку

<div class="radio-input-container"></div>

В итоге у нас получится следующая конструкция:

<div class="radio-input-container">
<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>
<?php
wc_dropdown_variation_attribute_options(
array(
'options'   => $options,
'attribute' => $attribute_name,
'product'   => $product,
)
);
?>
</div>

в js файл со скриптами добавляем:

$('.radio-input-container label').on('click', function(){
var Value = $(this).text();
var Label = $(this);
$('.radio-input-container label').removeClass('active');
Label.addClass('active');
Label.parent().find('select').val(Value).change();
});

Я также добавил очистку наших «лейблов» по клику на ссылку «Очистить»:

$('.reset_variations').on('click', function(){
$('.radio-input-container label').removeClass('active');
});

и следующие стили получились:

.radio-input-container {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 15px;
label {
width: 20%;
text-align: center;
border: 1px solid @colorGrey;
border-radius: 5px;
padding: 6px 15px 5px 15px;
cursor: pointer;
font-weight: 500;
&:hover, &.active {
border-color: @colorRed;
background: @colorWhite;
}
}
select {
display: none;
}
}

Select я спрятал намеренно, что не портило дизайн и не путало пользователя.

В итоге получилась такая вот красота:

w3c validator ругается на />

При проверке очередного проекта валидатором w3c, он начал ругаться на закрывающуюся ‘/’.

Self-closing tag syntax in text/html documents is widely discouraged; it’s unnecessary and interacts badly with other HTML features (e.g., unquoted attribute values). If you’re using a tool that injects self-closing tag syntax into all void elements, without any option to prevent it from doing so, then consider switching to a different tool.

Перевод:

Синтаксис самозакрывающихся тегов в документах text/html не рекомендуется; это не нужно и плохо взаимодействует с другими функциями HTML (например, значениями атрибутов без кавычек). Если вы используете инструмент, который внедряет синтаксис самозакрывающегося тега во все пустые элементы без возможности предотвратить это, подумайте о переходе на другой инструмент.

Интересное наблюдение… Кто не знал — берите на вооружение…

Хотя, вроде как, месяца полтора-два назад еще небыло такого…

Ну и, конечно же, warning’и на h2-h6 в <section> и/или <article> они не убрали… Хотя тоже странно. По семантике html5 внутри ставишь <header> и это корректно и валидно… Однако валидатор w3c думает иначе.

Изображение как фон для email-подписи

Всем привет.

Сейчас email-подписи стали не то, что очень популярны, а являются неотъемлемой частью практически любого сервиса. И мы говорим не только о триггерных рассылках или спаме… Нет, сюда входит абсолютно любое электронное письмо, которое отправляется в бизнес целях.

Вот и я верстал очередной макет для email-подписи одного из клиентов. И столкнулся с определенной проблемой. Мне необходимо было сделать так, чтобы фоновое изображение тянулось на весь макет. Однако, оказалось, что сделать это не так уж и просто.

CSS для background-image для email-подписи

Задача, которая была поставлена, в том, чтобы добиться отображения макета, как указано выше на изображении. Однако на практике получилось, что стили CSS для background резались фильтром gmail-сервиса.

Получается, что правило:

background: ulr('/path_to_file') no-repeat 100% 100%;

фильтр обрезает до конструкции

background: ulr('/path_to_file') no-repeat

И на выходе мы получаем что-то подобное этому

Вставка фона изображением в email-подпись

Окей, смотрим в сторону альтернативы и более обьемного описания того, чтобы задать размеры и положение фонового изображения, когда каждое правило пишется отдельно

background-image: url('/path_to_file');

background-repeat: no-repeat;

background-position: 100% 100%;

Однако, данная конструкция также обрезается фильтром почтовой системы или фильтром почтового клиента. В итоге мы получаем что-то такого плана:

background-image: url('/path_to_file');

background-repeat: no-repeat;

После некоторого «курения манов» и перелопачивания кучи ссылок и справочной информации, было найдено решение.

Правила для размеров и положения фонового изображения необходимо записывать в виде правила через ‘/’.

background: url('/path_to_file') no-repeat top / 100% auto;

Такую конструкцию пропустит фильтр почтового сервиса и на выходе мы получим то, что требуется.

ЗЫ: также хочу отметить еще иные результаты изучения справочной информации. Для верстки подписи не подходит позиционирование абсолютное и отрицательные margin.

Эти конструкции также будут фильтроваться и обрезаться фильтром почтовой системы.

Итого:

position: absolute;

и

margin-top: -100px;

Не пройдут проверку и будут обрезаны в финальном виде и не будут применены. Это также нужно учитывать.

Всем хорошего и валидного кода.