Иван Данилин

Иван Данилин

Fullstack WordPress Developer

Столкнулся с проблемой градиентов SVG-иконок в Элементоре. Если нужно вывести одну иконку в нескольких местах страницы, отобразится только первая. Причина в дублях ID градиентов в SVG. То есть проявится это может не только в градиентах, но и с другой стилизацией, использующей ID внутри SVG. Никогда не сталкивался с подобным. Видимо в Элементоре не попадались градиентные иконки. А в своей верстке обычно заливаю SVG в бэкграунд или использую спрайты.

Можно руками изменить ID и использовать разные SVG. Но если иконка используется раз так пятьдесят на странице (как у меня), получается какая-то глупость.

Еще можно загрузить обесцвеченный SVG и разукрашивать его при помощи CSS, но тоже как-то много телодвижений и заказчику такое для дальнейшего использования не отдашь.

Самое быстрое и бронебойное решение это фильтрануть перед выводом контент и с помощью preg_replace уникализировать ID.

Примерно так:

// Пофиксить градиентные иконки

function dnln_fix_svg_gradients($content) {
	if (strpos($content, '<svg') === false) {
		return $content;
	}

	$content = preg_replace_callback('/<svg[^>]*>.*?<\/svg>/is', function($matches) {
		$svg = $matches[0];
		$unique = uniqid('svgfix_');

		// Собираем все ID внутри <svg>
		preg_match_all('/id="([^"]+)"/', $svg, $ids);
		if (!empty($ids[1])) {
			foreach ($ids[1] as $oldId) {
				$newId = $oldId . '_' . $unique;
				// Меняем сам id
				$svg = preg_replace('/id="'.preg_quote($oldId, '/').'"/', 'id="'.$newId.'"', $svg);
				// Меняем все ссылки url(#id)
				$svg = preg_replace('/url\(#'.preg_quote($oldId, '/').'\)/', 'url(#'.$newId.')', $svg);
				// Меняем href="#id" и xlink:href="#id"
				$svg = preg_replace('/(["\'])#'.preg_quote($oldId, '/').'(["\'])/', '$1#'.$newId.'$2', $svg);
			}
		}

		return $svg;
	}, $content);

	return $content;
}

add_filter('the_content', 'dnln_fix_svg_gradients', 20);
add_filter('elementor/frontend/the_content', 'dnln_fix_svg_gradients', 20);

Код в functions.php активной темы.

Да, костыль. Кто знает более элегантные способы, пожалуйста, напишите.

Спасибо

  1. Ох, это же квест! 😄 Поймал идею — фильтрануть и preg_replace, почти как в Гонке Титанов, только вместо эльфов — SVG и ID. Зато бронебойное решение для 50 иконок — это же искусство! 😎 А что, костыль? В WordPress ведь без них и не обойтись, как без плагина NextGen Gallery для фотохоллов! 😉 В общем, держим кулачки за этого мастера, чтобы он нашел элегантный способ, а то глупость с уникальными ID — это уже серьезно! 👍