Недавно мне понадобилось добавить в некоторые материалы на сайте под управлением Joomla дополнительный текст — ссылку на Яндекс Диск с файлами. Ручное редактирование заняло бы слишком много времени, поэтому я решил автоматизировать задачу с помощью Python. В этой статье я расскажу, как это сделал.
Задача
Нужно было добавить в конец материалов из категории с ID 14 текст:
Текст для добавления:
<div class="yadisk">
Файлы, связанные с материалом, перемещены на Яндекс Диск по ссылке <a href="https://disk.yandex.com/d/Y07UWUtIk5PE2w" target="_blank">https://disk.yandex.com/d/Y07UWUtIk5PE2w</a>
</div>
Но не во все материалы, а только в те, чьи заголовки содержат слова "landrover", "defender" или "td5". Например, статья "Land Rover Defender Td5 Maintenance" должна получить этот текст, а "General Car Tips" — нет.
Решение
Я написал простой скрипт на Python, который подключается к базе данных Joomla, проверяет заголовки и обновляет поле fulltext нужных материалов. Вот как это выглядело.
Шаг 1: Подготовка
Сначала я настроил подключение к базе данных Joomla через библиотеку pymysql. Конфигурацию (хост, пользователь, пароль, имя базы) я вынес в файл .env для безопасности:
import pymysql
import os
from dotenv import load_dotenv
import logging
load_dotenv()
logging.basicConfig(level=logging.INFO, format='%(asctime)s:%(levelname)s:%(message)s')
jedig_db_config = {
'host': os.getenv('JEDIG_MYSQL_HOST'),
'user': os.getenv('JEDIG_MYSQL_USER'),
'password': os.getenv('JEDIG_MYSQL_PASSWORD'),
'db': os.getenv('JEDIG_MYSQL_DATABASE'),
'charset': 'utf8mb4',
'cursorclass': pymysql.cursors.DictCursor
}
Префикс таблицы у меня был dyutb_, так как это Joomla на сайте jedig.ru.
Шаг 2: Определение текста
Я создал переменную с HTML-текстом, который нужно добавить:
yadisk_text = '''
<div class="yadisk">
Файлы, связанные с материалом, перемещены на Яндекс Диск по ссылке <a href="https://disk.yandex.com/d/Y07UWUtIk5PE2w" target="_blank">https://disk.yandex.com/d/Y07UWUtIk5PE2w</a>
</div>
'''
Класс yadisk я добавил, чтобы потом легко найти и заменить этот блок, если потребуется.
Шаг 3: Основная функция
Вот сама функция, которая делает всю работу:
def append_yadisk_text():
jedig_connection = pymysql.connect(**jedig_db_config)
try:
with jedig_connection.cursor() as jedig_cursor:
jedig_cursor.execute("""
SELECT `id`, `title`, `fulltext`
FROM `dyutb_content`
WHERE `catid` = 14
""")
items = jedig_cursor.fetchall()
for item in items:
title_lower = item['title'].lower()
keywords = ['landrover', 'defender', 'td5']
matches_keywords = any(keyword in title_lower for keyword in keywords)
if matches_keywords:
current_fulltext = item['fulltext'] or ""
if not current_fulltext.strip().endswith(yadisk_text.strip()):
updated_fulltext = current_fulltext + yadisk_text
jedig_cursor.execute("""
UPDATE `dyutb_content`
SET `fulltext` = %s
WHERE `id` = %s
""", (updated_fulltext, item['id']))
logging.info(f"Добавлен текст в материал ID: {item['id']}, Заголовок: {item['title']}")
jedig_connection.commit()
logging.info("Обработка завершена.")
except Exception as e:
logging.error(f"Ошибка: {e}")
finally:
jedig_connection.close()
append_yadisk_text()
Что тут происходит:
- Выбираю материалы из категории 14 с помощью SQL-запроса.
- Для каждого материала проверяю заголовок на наличие ключевых слов.
- Если заголовок подходит, добавляю текст в конец
fulltext, но только если его там ещё нет (проверка черезendswith). - Обновляю базу и логирую изменения.
Шаг 4: Запуск
Я сохранил скрипт в файл, например, add_yadisk.py, и запустил его:
python add_yadisk.py
В логах увидел, какие материалы обновились, например:
2025-03-11 10:15:23,456:INFO:Добавлен текст в материал ID: 123, Заголовок: Land Rover Defender Td5 Maintenance 2025-03-11 10:15:23,789:INFO:Обработка завершена.
Результат
Теперь в конце нужных материалов появился блок со ссылкой на Яндекс Диск. Например, если открыть статью "Land Rover Defender Td5 Maintenance" в админке Joomla или на сайте, внизу будет:
При этом материалы без ключевых слов остались нетронутыми.
Вывод
Python оказался отличным инструментом для автоматизации работы с Joomla. Скрипт сэкономил мне часы ручного труда, а логи помогли убедиться, что всё прошло как надо. Если нужно будет что-то подобное сделать снова, я просто адаптирую этот код под новую задачу.
Полный код:
import pymysqlimport osfrom dotenv import load_dotenvimport logging
load_dotenv()logging.basicConfig(level=logging.INFO, format='%(asctime)s:%(levelname)s:%(message)s')
jedig_db_config = { 'host': os.getenv('JEDIG_MYSQL_HOST'), 'user': os.getenv('JEDIG_MYSQL_USER'), 'password': os.getenv('JEDIG_MYSQL_PASSWORD'), 'db': os.getenv('JEDIG_MYSQL_DATABASE'), 'charset': 'utf8mb4', 'cursorclass': pymysql.cursors.DictCursor}
jedig_table_prefix = 'dyutb_'
# Текст для добавления в конец материаловyadisk_text = '''<div class="yadisk"> Файлы, связанные с материалом, перемещены на Яндекс Диск по ссылке <a href="https://disk.yandex.com/d/Y07UWUtIk5PE2w" target="_blank">https://disk.yandex.com/d/Y07UWUtIk5PE2w</a></div>'''
def append_yadisk_text(): jedig_connection = None try: jedig_connection = pymysql.connect(**jedig_db_config) with jedig_connection.cursor() as jedig_cursor: # Выбираем материалы из категории 14 jedig_cursor.execute(f""" SELECT `id`, `title`, `fulltext` FROM `{jedig_table_prefix}content` WHERE `catid` = 14 """) items = jedig_cursor.fetchall()
for item in items: title_lower = item['title'].lower() keywords = ['landrover', 'defender', 'td5'] matches_keywords = any(keyword in title_lower for keyword in keywords)
if matches_keywords: current_fulltext = item['fulltext'] or "" # Проверяем, нет ли уже этого текста в конце if not current_fulltext.strip().endswith(yadisk_text.strip()): updated_fulltext = current_fulltext + yadisk_text jedig_cursor.execute(f""" UPDATE `{jedig_table_prefix}content` SET `fulltext` = %s WHERE `id` = %s """, (updated_fulltext, item['id'])) logging.info(f"Добавлен текст Яндекс Диска в материал ID: {item['id']}, Заголовок: {item['title']}") else: logging.info(f"Текст Яндекс Диска уже присутствует в материале ID: {item['id']}, Заголовок: {item['title']}")
jedig_connection.commit() logging.info("Обработка завершена.")
except Exception as e: logging.error(f"Ошибка при выполнении скрипта: {e}") finally: if jedig_connection: jedig_connection.close()
if __name__ == "__main__":
append_yadisk_text()