Недавно мне понадобилось добавить в некоторые материалы на сайте под управлением 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 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
}
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()