Инструменты экспорта контента для NetCat
Этот рецепт позволяет создать симпатичные кнопки для печати, отправки по e-mail, экспорта в DOC и PDF содержимого текущей страницы в любом оформлении. Рецепт раскрывает методику, подход к решению задачи.
Версия NetCat: любая
Дата обновления: 2012-09-23
Источники: www.mpdf1.com, www.position-absolute.com/articles/printing-web-pages-a-new-jquery-printing-plugin/
Идея и архитектура
Нам захотелось создать универсальное удобное решение для создания кнопок печати, вывода в pdf и doc, отправки на email. Нам нравилось, как такие кнопки реализованы в Joomla. Также нас вдохновил движок PmWikiPh?, в котором действие в отношении страницы определяется просто в адресной строке, например вот так: ?action=print
. Мы решили соединить эти два подхода и вплести их в архитектуру NetCat. В результате нескольких экспериментов, родился настоящий рецепт, суть работы которого можно кратко описать так:
- за обработку команд адресной строки отвечает специальный служебный макет дизайна
- в нем происходит подключение необходимых для совершения действий сторонних бесплатных скриптов, либо самостоятельная обработка страницы
- его же можно использовать для стилизации выводов, если в этом есть необходимость
- совершение действия с контентом текущей страницы сводится к открытию ссылки, содержащий указание на служебный макет дизайна и желаемого действия. То есть добавив к адресу любой страницы
?template=XX&action=MakePDF
мы получим эту же страницу в виде PDF-файла
Пример работы и инструкция по установке
Attach:phph-export2doc.zip - архив скрипта-преобразователя html в doc
Архив технических размышлений и процесса проектирования
Как все работает сейчас:
Печать: забирает из div c ID контент, генерит окно, отправляет на печать, закрывает.
Отправка по почте: на кривом jQuery генерит всплывающее окошко, после ввода адреса, отправляет встроенной функцией NetCat (прописана в Системных настройках, там же верстка похоже)
Вывод в .doc: хранит нужные функции в modules / default / func.inc.php. Специальная функция генерит ссылку (добавляет к текущему адресу ?action=MakeDoc ). В Компоненте ИЛИ Макете по условию action=MakeDoc вызывается функция ff_makeDoc, которая берет текущую страницу с isNaked, форматирует ее (вырезает все лишнее) и отдает как .doc
Вывод в .PDF: если в адресной строке conv=1, то в "объекте в списке" в php инклюдится неведомая хрень, в которую пропихивается отдельная верстка.
Как все должно быть:
Должны быть виджеты, которые можно встроить в любой Компонент, Макет или Объект на каждое из этих действий. И так, чтобы не надо было ничего больше вписывать-встраивать и дополнительно вызывать.
В виджете должно быть можно выбрать откуда цапать инфу. Настройки виджета:
- ID div'a для забора контента. Если это текстовое поле заполнено, то виджет через jQuery берет в качестве контента то, что лежит в элементе с таким ID.
- это не знаю пока как будет работать для PDF'a, DOC'a и впрочем email'a тоже :) Возможно, чтобы это заработало, придется все-таки вставлять обработку адресной строки в тот компонент, в котором вызывается виджет. Т.е. это может быть не универсальное решение, зато оно позволяет выводить на печать любой фрагмент страницы (объекта).
- еще подумал: пожалуй, слишком узкая функциональность. Если уж надо промутить такую штуку, как вывод куска страницы, но не isNaked и без доп. шаблона, то можно и заморочиться будет ручками. Так что отмена, не делаем этот функционал.
- это не знаю пока как будет работать для PDF'a, DOC'a и впрочем email'a тоже :) Возможно, чтобы это заработало, придется все-таки вставлять обработку адресной строки в тот компонент, в котором вызывается виджет. Т.е. это может быть не универсальное решение, зато оно позволяет выводить на печать любой фрагмент страницы (объекта).
- Если предыдущее поле пусто, то адресная строка для получения контента. По-умолчанию ?isNaked=1. Возможны варианты вручную : ?isNaked=1&nc_ctpl=219 (выводит компонент в нужном нам шаблоне) или еще какие-то. В этом случае мы можем по-человечески делать шаблоны для каждого типа вывода.
- более того, мы можем в адресной строке выбрать отдельный шаблон дизайна и печатать весь сайта на фирменных бланках
Рассмотрим примеры:
- Печать: генерит новое окошко нужного размера и, по-умолчанию открывает там ?isNaked, отправляет на печать, закрывает окошко.
- Отправка по почте: открывает маленькое поле для ввода e-mail, после отправки ajax-запросом отправляет через POST адрес на ?isNaked, где весь $html по условию наличия поста отправляется на почту
- Вывод в .doc: открывает новую страницу ?isNaked&action=MakeDoc , по условию выполняет функцию ff_makeDoc , передавая в нее $html
- Вывод в .PDF: открывает новую страницу ?isNaked&action=MakePDF, по условию инклюдит неведомую хрень и вызывает функции $mpdf-> ... передавая в нее $html
- можно конечно иклюднуть mpdf в modules/default/ , но мы не будем этого делать, ибо это огромная неведомая хрень (производительность + безопасность), которая будет включаться всегда
Подводные камни:
- кто будет обрабатывать условия? идеально, если сам виджет, тогда его можно будет цеплять куда угодно, кроме Макета Дизайна (потому что прицепив его к Макету, он вывалится при условии ?isNaked )
- выход: если мы собираемся использовать виджет для всего сайта (встроить в макет дизайна), создаем отдельный макет дизайна, в котором идет только обработка условий, и в настройках виджетов указываем не isNaked, а номер этого шаблона
- если это не сработает (обработка условий в самом виджете), то кто будет это делать? Либо шаблон компонента (геморройно), либо опять же отдельный шаблон дизайна.
Вывод:
- надо делать макет дизайна, который лишь обрабатывает команды ~MakeDoc, ~MakePdf, post с email'ом
- виджеты сводятся к настройке адресной строки, где можно указать нужный макет дизайна и, если хочется, нужный шаблон компонента для представления информации
- виджеты получаются такие примитивные, что мне лень их делать. Пусть кто-нить еще потренируется.
И окончательный вывод: виджеты не нужны вообще. Должен быть один макет дизайна, обрабатывающий параметры адресной строки и post.
Где угодно ставятся ссылки вида ?template=94&nc_ctpl=219&action=MakeDoc , где 94 - шаблон макета дизайна (обязательно), 219 - шаблон компонента (опционально), MakeDoc - что мы хотим получить на выходе
Итак, а теперь задача программисту.
Дано:
- на dekra.nic.ru в компоненте "Архив расчетов" в Полном Выводе Объекта и в Системных настройках всякая хрень, отвечающая за работу кнопок "печать", email и pdf.
- вот тут: templates.finar.ru/netcat-components/doc/ разработан алгоритм вывода странички в doc
Как примерно это сейчас работает:
- Печать: забирает из div c ID контент, генерит окно, отправляет на печать, закрывает.
- Отправка по почте: на кривом jQuery генерит всплывающее окошко, после ввода адреса, отправляет встроенной функцией NetCat (прописана в Системных настройках, там же верстка похоже)
- Вывод в .doc: хранит нужные функции в modules / default / func.inc.php. Специальная функция генерит ссылку (добавляет к текущему адресу ?action=MakeDoc ). В Компоненте ИЛИ Макете по условию action=MakeDoc вызывается функция ff_makeDoc, которая берет текущую страницу с isNaked, форматирует ее (вырезает все лишнее) и отдает как .doc
- Вывод в .PDF: если в адресной строке conv=1, то в "объекте в списке" в php инклюдится неведомая хрень, в которую пропихивается отдельная верстка.
Задача:
- переделать все заново на сайте http://templates.finar.ru/netcat-components/ в новом разделе скажем, "content-export-tools"
- выпилить с autocalc.pro из компонента все старое, связанное с этим функционалом
- внедрить на него, причем в ту верстку, которую сделает Татьяна
Как все переделать:
- берем с www.mpdf1.com обработчик PDF
- кладем его в /images/phph-mpdf/ , рядом его же в архиве. Исходные не модифициреум, если необходимо , то пишем сюда что и зачем правили
- создаем отдельный шаблон дизайна, пустой, скажем phph-content-exporter
- в шаблоне дизайна пишем: если в адресной строке action=MakePDF , то include /images/phph-mpdf/ и там в нем вызвать метод $mpdf->... и записать в него контент (см. примерно как на autocalc.pro ). Желательно научиться подцеплять css файл при этом.
- из modules / default / на templates.finar.ru забираем функции из function.inc.php все, кроме ff_link() , он не нужен
- пишем их в отдельный файл в /images/phph-export2doc/phph-export2doc.php , вырезаем все, что связано с ?isNaked=1
- в шаблоне дизайна пишем: если в адресной строке action=MakeDOC , то include обработчик doc'ов
- в шаблоне дизайна пишем: если методом post передан email, то взять контент страницы и отправить на этот e-mail
Это "серверная" часть, которая генерит и отдает файлы. Теперь сделаем кнопки, которые будут вызывать эти действия. Для всех кнопок давайте возьмем бутстраповские иконки.
- кнопка Печать. На jQuery (?) генерит новое окошко, в котором открывается %текущая_страница%/?template=94 , где 94 - номер шаблона phph-content-exporter , затем отправляет на печать и закрывает окошко (также как сейчас это сделано)
- кнопка "Отправить на email" . При нажатии рядом с ней появляется поле, куда можно ввести email. При подтверждении, осуществляется ajax-запрос по адресу %текущая_страница%/?template=94 , методом POST при этом передается значение email (примерно также сделано сейчас). Можно и номер темплейта наверное постом передать для единообразия.
- кнопка "Сохранить в PDF" и "Сохранить в DOC" работают идентично, только первая открывает в новом окне %текущая_страница%/?template=94&action=MakePDF , а вторая action=MakeDOC
- на странице "content-export-tools" описываем эти кнопки и приводим их код, а также пишем инструкцию по внедрению на другой сайт
- по этой инструкции внедряем на autocalc.pro . Весьма вероятно там придется выводить объекты через шаблоны компонента, так что ссылки в пунктах 9-12 придется поправить, удобную возможность чего можно тоже отразить в инструкции :)