JavaScript и PHP
JavaScript и PHP
ЯНЦЕВ
JAVASCRIPT И PHP.
CONTENT MANAGEMENT
SYSTEM
Учебное пособие
•САНКТПЕТЕРБУРГ•МОСКВА•КРАСНОДАР•
2022
УДК 004
ББК 32.973.4я73
ISBN 9785507448463
УДК 004
ББК 32.973.4я73
Обложка
П. И. ПОЛЯКОВА
1. ВВЕДЕНИЕ
Современные веб-ресурсы невозможно представить без систем управления,
которые принято называть Content management system (CMS).
Создание профессиональной системы управления — сложная и трудоем-
кая задача. И тем не менее многие разработчики используют не готовые CMS, а
пишут собственные. Иногда популярные системы, такие как WordPress, Joomla,
Drupal, 1С-Битрикс и др., оказываются слишком громоздкими для тех или иных
проектов. Поэтому рациональнее написать собственную, более простую, «зато-
ченную» под конкретную задачу. Это как с покосом травы на даче. Конечно,
можно запустить на участок комбайн, но гораздо проще справиться обычной
бензокосилкой.
Автор начал заниматься программированием в 2003 г. С 2004 г. за до-
вольно короткий промежуток времени успел поработать в нескольких студиях
веб-дизайна. И вот на что обратил внимание. В те годы почти каждая такая сту-
дия, большая или маленькая, старалась написать собственные «движки» для
сайтов. Получались они очень разными — от весьма простеньких и неказистых
до серьезных профессиональных разработок.
Не остался в стороне от этой моды и автор. Только писал такие системы не
во взаимодействии с группой программистов и дизайнеров, а полностью само-
стоятельно. Назывались они непритязательно — СОУС (Система оперативного
управления сайтом), ИКС (Интерактивный конструктор сайтов), КПСС (Кон-
структор простых социальных сетей). Естественно, автор постоянно их совер-
шенствовал, наращивал функциональные возможности и т. д. До 2020 г. автор и
многие его клиенты вполне успешно пользовались данными разработками.
Однако наступил момент, когда автор уже не мог в одиночку конкуриро-
вать с такими проектами, как WordPress, Joomla, Drupal, 1С-Битрикс и др.
В итоге все мои системы постепенно были отправлены в архив, после че-
го автор занялся другими разработками. Но по-прежнему интересовался тем,
что происходит в индустрии создания «движков». А самое главное, продолжал
заниматься написанием различных компонентов, которые являлись составными
частями CMS.
У читателей, наверное, уже появился вопрос: к чему этот исторический экс-
курс? Он демонстрирует, что на сегодняшний день у автора накопился немалый
опыт создания самых разных CMS и их отдельный частей для самых разных веб-
проектов. Этим опытом автор и хочет поделиться на страницах данной книги.
3
Есть ряд книг, в которых излагаются не только основы языка, но и даются
примеры сценариев. Они могут объяснить начинающему разработчику, каким
образом создаются реальные проекты.
Но изданий, рассказывающих о такой популярной среди программистов
теме, как создание CMS, практически нет. Частично автор попытался осветить
этот вопрос в своем учебнике «JavaScript. Визуальные редакторы». Но там рас-
сказ велся лишь об одной из составных частей CMS — редакторах WYSIWYG.
Поэтому автор решил написать новую книгу, целиком посвященную теме
создания полностью законченной системы управления, которая позволяла бы
конструировать сайты с нуля. Специально для данной книги было написано до-
вольно простое ПО, которое и будет рассмотрено в дальнейшем.
Но это будут не просто теоретические рассуждения. Если в книге пред-
ставлены лишь фрагменты кода, то, скачав по ссылке https://editjs.ru/CMS.zip
zip-архив, вы получите в свое распоряжение весь проект, включая сам движок и
демонстрационный сайт, выполненный в двух вариантах. Вы можете проверить
в действии и сайт, и систему управления. А также читать книгу и одновременно
изучать «живой» код, записанный в тех или иных файлах.
4
ном окне, а прямо в самой странице. Благодаря этому требуемый результат до-
стигается с первой попытки.
Еще один важный момент. Как ясно из названия книги, главные действу-
ющие лица в ней — языки программирования JavaScript и PHP. Первое место
по объему кода занимает JavaScript, соответственно PHP — второе, отставая не
на много. Поэтому было бы неплохо, чтобы читатель знал основы этих языков
хотя бы на уровне начинающего.
HTML-разметке и таблицам стилей CSS мы тоже уделим внимание, так
как их доля в коде проекта заметна. Поэтому быть знакомыми с HTML и CSS
читателю также необходимо.
На что еще хотел бы обратить внимание читателя: во избежание терми-
нологических споров по языку JavaScript автор ориентировался на определения,
данные на страницах сайта https://developer.mozilla.org/ru/.
function coor(ev)
{
let v=ev.pageY;
let sv=document.getElementById("bpan").offsetTop;
dv=v-sv;
addEventListener("mousemove", neco);
}
5
Однако подобный код занимает в книге слишком много места. Поэтому
автор применил сокращенную форму записи стилей, например так:
Как видите, экономия налицо: в этом случае вместо девяти строк на за-
пись потрачено только три.
И последнее. В описании программ нередко имеет смысл не приводить
весь код, который относится к разбираемому фрагменту, а показывать только ту
его часть, что важна в контексте данных объяснений. Поэтому в таких случаях
автор вводит сокращение в виде трех точек:
...
Тем самым мы показываем, что на данном этапе описания нам важно об-
ратить внимание исключительно на позиционирование элемента.
6
2. ПРЕЖДЕ ЧЕМ НАЧАТЬ
До того как мы приступим к написанию CMS, автор посчитал необходи-
мым дать некоторую предварительную информацию:
— подробнее коснуться того, что такое CMS;
— рассказать, какие технологии и методы необходимо будет применить
в нашем проекте, в первую очередь в визуальном редакторе;
— пояснить смысл терминов, которые нам придется использовать неод-
нократно.
Поэтому данный материал я решил выделить пусть и в небольшую, но
самостоятельную главу.
2.1. CMS
Представим такую ситуацию: вы разработали сайт, состоящий из несколь-
ких HTML-страниц, и разместили его в Сети. Пройдет немного времени — и вы
обнаружите, что информацию на одной или нескольких страницах необходимо
отредактировать, а может, и кардинально изменить. Даже самые стабильные ин-
тернет-ресурсы нуждаются в периодическом обновлении. А что говорить про
сайты, которые рассказывают о быстро меняющихся вещах, например о строи-
тельстве жилого микрорайона или о новинках в мире компьютеров. В таких слу-
чаях обновление информации происходит чуть ли не каждый день.
И вот вы стоите перед задачей ежедневно редактировать одну или не-
сколько страниц и ставить их вместо устаревших версий. Выглядит это при-
мерно так: открыли на своем компьютере папку с файлами сайта, добавили но-
вые рисунки, схемы или фотографии, отредактировали страницу, подключи-
лись к хостингу, закачали новые изображения, заменили страницу, запустили
браузер, проверили полученный результат. Если что-то не понравилось, вновь
правите страницу и закачиваете ее новую версию на хостинг. Уже чувствуется,
что это довольно хлопотное занятие. Между тем, если бы ваш сайт был снаб-
жен CMS, все оказалось бы гораздо проще: запускаете в браузере систему
управления и выполняете все манипуляции через нее. Не надо подключаться к
хостингу, не надо переносить страницу на свой компьютер, не надо закачивать
отредактированную страницу через файловый менеджер. Еще раз повторим: все
делается через браузер и без предварительной обработки данных на своем ком-
пьютере.
Обычно CMS — это симбиоз двух продуктов: конструктора сайта и си-
стемы управления сайтом. В Сети рекламируется много различных CMS,
например уже упоминавшиеся во введении WordPress, Joomla, Drupal, 1С-
Битрикс и др.
Аббревиатура CMS происходит от английского Content management
system, что переводится как система управления содержимым. Многие совре-
менные сайты (если не большинство) управляются такими системами. CMS поз-
7
воляют администратору вносить любые изменения на страницы сайта в онлайн-
режиме. Для этого системы управления снабжают WYSIWYG-редакторами.
2.2. WYSIWYG
Сайты пишутся на языках программирования HTML и JavaScript. Поэто-
му редактирование веб-страницы — это по сути процесс изменения ее кода.
Для профессионального разработчика — это привычное занятие. Но ведь боль-
шинство сайтов программисты создают не для себя, а для клиентов. Много ли
среди них специалистов, досконально знающих HTML и JavaScript? Ответ —
единицы. Значит, для большинства клиентов необходим механизм, который бы
позволял создавать на сайте новые страницы и редактировать существующие
без специальных знаний.
Поэтому креативные программисты придумали не простой редактор,
а WYSIWYG (или, как еще говорят, визуальный редактор). Он отображает ре-
дактируемые материалы практически в том же самом виде, как и на странице
сайта. То есть нажали кнопку «BOLD=» — фрагмент текста действительно вы-
делился жирным. Нажали кнопку «IMG» — и появилась настоящая фотогра-
фия, а не ее HTML-код.
Термин WYSIWYG — это аббревиатура, произошедшая от английского
выражения What You See Is What You Get, что в переводе означает «что вы ви-
дите, то вы и получаете». В нашем случае смысл этого выражения таков: что вы
видите в редакторе, то и будет на странице сайта. Очень удобно для создания и
редактирования контента!
8
или присвоить его в JavaScript-сценарии:
document.getElementById("edit").
setAttribute("contenteditable", true);
frames[0].document.designMode="on";
addEventListener("load", function()
{
frames[0].document.designMode="on";
});
9
2.5. Метод getSelection
Теперь мы переходим к методам, которые предоставляет в наше распоря-
жение JavaScript.
Первым упомянем getSelection. Тут все очень просто: метод возвращает
объект Selection, который содержит выделенный пользователем текст. Разра-
ботчик имеет возможность на программном уровне манипулировать выделен-
ным фрагментом: форматировать его, копировать, удалять, изменять.
Как выглядит применение метода на практике? Например, у вас есть ре-
дактируемая область контента. Вы выделили в этой области одно или несколь-
ко слов и нажали кнопку BOLD. К тексту, содержащемуся в объекте Selection,
будет добавлена пара тегов b — открывающий и закрывающий. После этого те-
кущее выделение будет преобразовано к полужирному начертанию.
Аналогично происходит, если вы просто вставили курсор в какое-либо
место редактируемой области. Объект Selection в этом случае хранит точку
вставки курсора. В эту точку можно поместить рисунок, таблицу, линию,
символ и т. д.
let sel=document.getSelection();
let rng=sel.getRangeAt(0);
let elm=document.createElement("b");
rng.surroundContents(elm);
10
3. СРЕДА РАЗРАБОТКИ
Для написания и тестирования примеров из книги нам в обязательном по-
рядке необходимо создать на своем компьютере локальный хостинг.
Вообще, хостинг — это, проще говоря, компьютер, предназначенный для
размещения сайтов и обеспечивающий к ним доступ из Интернета. Локальный
хостинг — набор программ на вашем персональном компьютере, которые поз-
воляют имитировать реальный хостинг и проводить тестирование ваших сайтов
(включая HTML-страницы и серверные скрипты) перед их размещением в Се-
ти. Кстати, обратите внимание: локальный хостинг работает без подклю-
чения к Интернету!
Для чего нужен хостинг в нашем случае? Дело в том, что разбираемая
CMS написана не на чистом HTML, а на «смеси» HTML и PHP. То есть каждая
страница, которую видит посетитель или администратор системы управления,
представляет собой серверную PHP-программу, формирующую данную стра-
ницу вслед за запросом. А значит, открыть такую программу просто двойным
щелчком по иконке нельзя. Необходимо расположить скрипт на хостинге и за-
пускать, вводя соответствующий запрос в адресном поле браузера. Только в
этом случае вы увидите запрошенную страницу.
Чтобы получить результаты, описанные в данной книге, вам понадобится
установить на компьютер распространяемый пакет компонентов Visual C++ от
Microsoft, сервер Apache и интерпретатор PHP. Описание технологии их уста-
новки приведено в следующих разделах.
Полноценную среду разработки невозможно представить без настоящего
текстового редактора, специально предназначенного для создания программ.
Конечно, весь код можно писать в обычном «Блокноте». Но гораздо лучше и ра-
циональнее пользоваться специализированными редакторами. Такие приложения
намного удобнее: они подсвечивают код, предлагают синтаксические подсказки,
позволяют менять кодировку документов, сохраняют файлы в разных форматах.
В нашем случае необходим редактор, который позволит:
— выполнять качественную разметку;
— создавать файлы с таблицами стилей;
— писать сценарии на JavaScript;
— писать серверные приложения на PHP.
Этим принципам удовлетворяют многие редакторы. Но лучше всего, на
наш взгляд, Notepad++. Где его взять и как установить, рассказывается в пятом
разделе этой главы.
Итак, вводная часть завершена — приступим к созданию локального хо-
стинга. А начнем мы с выяснения разрядности вашей ОС.
Обратите внимание: все процедуры описаны для компьютера с опе-
рационной системой Windows 10.
11
3.1. Выясняем разрядность ОС
Перед тем как мы создадим на компьютере среду разработки, необходимо
выяснить разрядность вашей операционной системы, чтобы знать, какие файлы
скачивать для локального хостинга.
Включите компьютер, дождитесь полной загрузки операционной систе-
мы. Щелкните на кнопке «Пуск», а затем на кнопке «Параметры» (рис. 3.1.1).
В открывшемся окне выберите пункт меню «Система». Откроется следующая
вкладка, в которой необходимо кликнуть на строке «О системе» (или «О про-
грамме»). После этого на вкладке «Характеристики устройства» посмотрите
строку «Тип системы» (рис. 3.1.2).
Рис. 3.1.1
Кнопка «Параметры» в меню
Рис. 3.1.2
Разрядность или тип операционной системы
12
Типов ОС Windows существует два — 32-разрядная и 64-разрядная. За-
помните разрядность вашей. Это число понадобится трижды: при скачивании
пакета Visual C++, а также zip-архивов сервера Apache и интерпретатора PHP.
Рис. 3.2.1
Ссылки для скачивания пакетов Visual C++
Запустите скачанный файл (рис. 3.2.2). Примите условия лицензионного со-
глашения и нажмите кнопку «Установить». Дождитесь завершения процесса уста-
новки (рис. 3.2.3). Нажмите кнопку «Закрыть» (рис. 3.2.4).
13
Рис. 3.2.2
Начало установки пакета
Рис. 3.2.3
Процесс установки
Рис. 3.2.4
Завершение установки
14
3.3. Установка сервера Apache 2.4
Теперь скачайте на «Рабочий стол» компьютера с сайта
https://www.apache-lounge.com/download/ zip-архив сервера, соответствующий
разрядности вашей ОС (рис. 3.3.1). Для 64-разрядной системы — архив с по-
меткой Win64 (например, httpd-2.4.48-win64-VS16.zip), для 32-разрядной — с
пометкой Win32 (например, httpd-2.4.48-win32-VS16.zip). Распакуйте архив.
Скопируйте папку Apache24 (только ее) непосредственно на диск C, чтобы ее
адрес был C:\Apache24 (рис. 3.3.2).
Рис. 3.3.1
Сайт с zip-архивом сервера
Откройте приложение «Командная строка» от имени администратора. Для
этого нажмите кнопку «Пуск», в меню выберите «Служебные — Windows», найди-
те пункт «Командная строка» и щелкните на нем правой (!) кнопкой мыши. В вы-
падающем списке выберите «Дополнительно», а затем «Запуск от имени админи-
стратора» (рис. 3.3.3). Откроется окно программы.
Рис. 3.3.2
Копируем папку Apache24 на диск C
15
Рис. 3.3.3
Запуск командной строки
Теперь надо инсталлировать, а затем запустить сервер. Для этого в окне
командной строки сразу после:
C:\WINDOWS\System32>
наберите
C:\Apache24\bin\httpd.exe -k install
Должно получиться
C:\WINDOWS\System32>C:\Apache24\bin\httpd.exe -k install
C:\WINDOWS\System32>
16
Рис. 3.3.4
Инсталляция сервера из приложения «Командная строка»
Нам надо убедиться, что сервер заработал. Для этого откройте ваш брау-
зер и введите в строке адреса http://localhost/. Если появилось сообщение «It
works!», то все в порядке — сервер функционирует как положено (рис. 3.3.5).
Рис. 3.3.5
Сервер подтверждает, что он работает
Теперь обратите внимание на один важный момент. Метод, которым мы
установили сервер, позволяет запускать его автоматически при включении
компьютера и завершать его работу при выключении компьютера. То есть
Apache продолжает функционировать, даже если в данное время он вам не ну-
жен. Эта информация вызывает у вас беспокойство по поводу теоретической
уязвимости ПК? Тогда переведите сервер в режим ручного запуска. Для этого
выполните следующие действия:
— введите в строке поиска слово «службы» (рис. 3.3.6) и нажмите на со-
ответствующей иконке, которая появится в списке результатов поиска;
— в открывшемся окне найдите строку «Apache2.4» и щелкните на ней пра-
вой (!) кнопкой мыши — появится меню управления службой (рис. 3.3.7);
— кликните на строке «Свойства» и в окне на вкладке «Общие» найдите
список «Тип запуска»;
— выберите пункт «Вручную», затем последовательно нажмите кнопки
«Применить» и «ОК» (рис. 3.3.8);
— теперь остановите службу, нажав соответствующую ссылку в левой
стороне окна (рис. 3.3.9);
— дождитесь окончания процесса (рис. 3.3.10);
— закройте вкладку «Службы».
17
Рис. 3.3.6
Находим приложение «Службы»
Рис. 3.3.7
Открываем меню управления службой
18
Рис. 3.3.8
Переводим службу в режим ручного запуска
Рис. 3.3.9
Нажимаем ссылку «Остановить службу»
19
Рис. 3.3.10
Идет процесс остановки Apache
Теперь Apache остановлен и переведен в режим ручного запуска. При необ-
ходимости воспользоваться сервером снова зайдите в раздел «Службы», выделите
строку «Apache2.4» и кликните на ссылке «Запустить службу» (рис. 3.3.11). Подо-
ждите окончания процесса (рис. 3.3.12).
.
Рис. 3.3.11
Для запуска Apache нажмите ссылку «Запустить службу»
20
Рис. 3.3.12
Идет процесс запуска сервера
Продолжаете беспокоиться о безопасности? Можете на время работы с
сервером отключать свой ПК от Интернета. Напомню — локальный хостинг
работает без Сети.
DirectoryIndex index.html
и добавьте к ней
index.php
21
Рис. 3.4.1
Сайт с zip-архивом PHP
Рис. 3.4.2
Перемещаем папку php на диск C
22
Рис. 3.4.3
Файл httpd.conf
Должно получиться
<?php
echo "Good !";
Рис. 3.4.4
Проверяем работу PHP
23
3.5. Установка редактора Notepad++ 8
Скачать Notepad++ можно по адресу https://notepad-plus-
plus.org/downloads/ (рис. 3.5.1).
Устанавливается редактор следующим образом. Запустите скачанный файл.
В первую очередь появится окно выбора языка программы. Оставляем русский
(рис. 3.5.2) и нажимаем кнопку «ОК».
Рис. 3.5.1
Сайт с файлами редактора Notepad++
Рис. 3.5.2
Выбираем язык ПО
В следующем окне нажимаем кнопку «Далее» (рис. 3.5.3). Затем нажати-
ем кнопки «Принимаю» соглашаемся с условиями лицензии (рис. 3.5.4).
Рис. 3.5.3
Нажимаем кнопку «Далее»
24
Рис. 3.5.4
Соглашаемся с условиями лицензии
Теперь нам необходимо выбрать папку для установки программы.
По умолчанию предлагается C:\Program Files\Notepad++. Думаем, такой вари-
ант установки походит всем, поэтому данную папку оставляем без измене-
ний (рис. 3.5.5).
Рис. 3.5.5
Выбираем папку для установки программы
25
Дальше будет окно с выбором компонентов, которые можно установить
вместе с программой. Этот раздел предназначен в первую очередь для опыт-
ных программистов, каковыми мы пока не являемся. Поэтому здесь ничего не
меняем, жмем кнопку «Далее» (рис. 3.5.6).
Рис. 3.5.6
Здесь ничего не меняем, жмем кнопку «Далее»
На последнем этапе перед началом непосредственной установки на вкладке
появится пункт «Create Shortcut on Desktop» (рис. 3.5.7). То есть нам предлагают со-
здать ярлык программы на рабочем столе. Делать это или нет — зависит от вашего
желания. Замечу, что после установки редактора ссылка на него добавится в кон-
текстное меню. Достаточно будет навести указатель мыши на файл, щелкнуть пра-
вой клавишей, и в списке возможных действий вы увидите строку «Edit with
Notepad++». Кликните по ней — и файл будет открыт в редакторе.
Рис. 3.5.7
Нажимаем кнопку «Установить»
26
Разобравшись с вопросом, необходим ли ярлык на рабочем столе или нет,
нажмите кнопку «Установить». Дождитесь окончания процесса (рис. 3.5.8).
После завершения установки вам нужно будет принять еще одно решение:
сразу запустить программу или отложить это дело «на потом». Для этого оставьте
или снимите галочку в пункте «Запустить Notepad++» (рис. 3.5.9). Теперь нажмите
кнопку «Готово». Поздравляю — отныне на вашем компьютере установлен про-
фессиональный текстовый редактор!
Рис. 3.5.8
Ждем окончания процесса
Рис. 3.5.9
Завершение установки
Познакомимся с ним поближе. Как выглядит редактор, вы можете уви-
деть на рисунке 3.5.10.
Notepad++ позволяет:
— выполнять поиск по файлу в разных направлениях;
— производить замену по шаблону;
27
— устанавливать кодировки, в том числе необходимую для нашего про-
екта UTF-8;
— менять страницы, форматируя их по стандартам разных операционных
систем — Windows, Unix или macOS;
— подсвечивать код, выделяя разные по назначению фрагменты, опера-
торы, функции, переменные, комментарии и т. д.;
— выбирать синтаксис документа (благодаря чему меняются варианты
подсветки кода), например HTML, CSS, JavaScript или PHP;
— сохранять файлы с разным расширением;
— менять стили оформления окна программы — вариантов достаточно,
найдется любой по желанию;
— выполнять еще многие и многие операции.
Рис. 3.5.10
Редактор Notepad++ с открытым в нем файлом JavaScript
28
— скопируйте содержимое папки CMS\htdocs_1 — все файлы и каталоги
(это версия системы с уже готовым демонстрационным сайтом);
— поместите скопированные файлы и каталоги в папку
C:\Apache24\htdocs;
— запустите браузер и в строке адреса введите http://localhost/ — загру-
зится главная страница демонстрационного сайта, разработанного на нашей
CMS (рис. 3.6.1);
— чтобы посмотреть код любого из разбираемых в той или иной главе
файлов, открывайте их в редакторе Notepad++.
Рис. 3.6.1
Главная страница проекта, запущенного на локальном хостинге
30
Рис. 3.7.1
Процесс подготовки файла к переносу на хостинг
Сейчас автор познакомит вас со способом, который используют крайне
редко, — и напрасно. Способ настолько прост, что дальше некуда. Для этого
мы воспользуемся стандартной программой «Проводник», которую предостав-
ляет операционная система Windows.
1. Откройте любую папку на вашем компьютере и в левой верхней строке
введите адрес вашего сайта по ftp-протоколу (рис. 3.7.2).
Рис. 3.7.2
Начинаем процесс входа на хостинг по протоколу ftp
2. Появится окно для входа на ftp-сервер. Введите в нем имя пользователя
(логин) и пароль (рис. 3.7.3).
31
Рис. 3.7.3
Ввод имени пользователя и пароля
3. Откроется папка, предназначенная для файлов вашего сайта. Скопи-
руйте все компоненты проекта и переместите их на хостинг (рис. 3.7.4).
Рис. 3.7.4
Загружаем файлы проекта в папку вашего сайта
Следующий этап работ — редактирование файла .htaccess и установка
прав на файлы PHP.
32
Файл .htaccess чаще всего изначально находится в папке, созданной про-
вайдером для вашего сайта. Этот файл необходим, чтобы указать индивидуаль-
ные настройки сервера. Обычно администрация хостинга предоставляет необ-
ходимую информацию по таким настройкам.
Что касается установки прав на файлы PHP, мы рассмотрим два варианта
таких действий.
1. Если вы загружали проект через «Проводник», то можете сразу после
перемещения файлов установить необходимые права. Для этого щелкните на
пиктограмме файла правой (!) кнопкой мыши. В открывшемся меню выберите
пункт «Свойства» (рис. 3.7.5) и кликните на нем. Появится окно настроек
(рис. 3.7.6). Здесь можно установить права на чтение, запись и выполнение для
разных пользователей. Нужно установить следующие разрешения:
— владельцу — на чтение, запись и выполнение;
— группе — на чтение и выполнение;
— всем пользователям — на чтение и выполнение.
Завершайте процесс нажатием кнопки «ОК».
2. Выполнить настройки прав в панели управления. Один из вариантов
может выглядеть так (на примере хостинга SpaceWeb):
— щелкаете правой кнопкой мыши на пиктограмме файла;
— в открывшемся меню выбираете пункт «Изменить права доступа»;
— устанавливаете их для разных пользователей согласно описанию, при-
веденному выше (рис. 3.7.7), — в результате в окне «Разрешение» должны по-
явиться цифры 755.
Рис. 3.7.5
Выбор пункта «Свойства» из контекстного меню
33
Рис. 3.7.6
Установка прав доступа к файлу в «Проводнике»
Рис. 3.7.7
Установка прав доступа в панели настроек хостинга
Теперь узнайте у своего провайдера номера DNS-серверов (обычно их коли-
чество от 2 до 4). На сайте регистратора зайдите на свою страницу, откройте вклад-
ку с перечнем ваших доменов и кликните ссылку «Делегировать» напротив имени
нужного домена (рис. 3.7.8 — показано на примере компании RU-CENTER). От-
кроется страница управления DNS-серверами (рис. 3.7.9). Заполните поля под стро-
кой «DNS-сервер» и нажмите кнопку «Сохранить изменения». Будьте готовы к то-
34
му, что придется подождать несколько часов, пока ваш сайт не станет виден
в Интернете.
Рис. 3.7.8
Страница с перечнем ваших доменов
Рис. 3.7.9
Страница управления DNS-серверами
Этап под названием «тестирование и устранение проблем». Обычно
ошибки в работе сайта возникают по следующим причинам:
— забыли перекодировать какой-то файл из Windows в Unix-формат;
— забыли изменить права доступа какого-нибудь исполняемого файла;
— указали не все необходимые настройки в файле .htaccess.
Обязательно проверьте все функции вашего сайта, чтобы убедиться в от-
сутствии проблем!
Ваш проект заработал? Пора заняться его раскруткой. Дело это настолько
непростое, что автор советует прочитать специальные книги с рекомендациями
по продвижению и аналогичные статьи в Интернете.
35
4. ТЕСТИРОВАНИЕ ПРОГРАММ
Как ни хороши современные веб-обозреватели, но кое-чем они автору ка-
тегорически не нравятся. А именно тем, что в них все очень тщательно проду-
мано и предусмотрено. В результате, даже получив некачественный код, брау-
зеры понимают, чего хотел добиться программист, и демонстрируют правиль-
ную веб-страницу. А это провоцирует разработчиков небрежно относиться к
своим обязанностям. В результате миллионы сайтов за красивой оболочкой со-
держат множество ошибок и нарушений стандартов, которые веб-обозреватели
успешно исправляют.
Удивительно, но даже в ресурсах лидеров мировой веб-индустрии немало
ошибок и нарушений.
Большинство из таких сайтов сделаны на популярных «движках», как
иногда называют всем известные CMS. Ошибки и отклонения от стандартов за-
ложены у них в модулях, формирующих страницы.
Автор относится к тому немногочисленному отряду программистов, ко-
торые выпускают «продукцию» в свет, только добившись абсолютно чистого
кода. Поэтому я проверил разметку, стили и сценарии самым тщательным обра-
зом. Вот перечень проведенных работ:
— проверка работоспособности сценариев в различных браузерах, в том
числе достижение идентичности результатов показа страниц;
— проверка кода с помощью валидаторов и устранение ошибок.
Подробнее об этом — в следующих разделах.
37
— валидатор CSS3 — http://jigsaw.w3.org/css-validator/.
Данные валидаторы очень удобны. Они позволяют проверять разметку и
таблицы стилей:
— страниц, уже загруженных в Сеть;
— файлов, загруженных в валидатор с вашего компьютера;
— в коде, скопированном из вашего файла и помещенном в специальное
текстовое поле.
Например, после обработки кода разметки все ошибки и предупреждения
с комментариями на английском языке появятся на странице HTML-валидатора
в ее нижней части. При этом ошибки будут сопровождаться надписью Error на
розовым фоне, а предупреждения — надписью Warning на желтом фоне.
Например, строка кода <script type="text/javascript"> получит предупрежде-
ние, так как по современным стандартам указывать тип скрипта не надо, но в то
же время данная ошибка некритична, так как не мешает нормальному отобра-
жению страницы. Зато следующая строка <img src="img/im1.jpg"> будет от-
мечена надписью Error, так как у рисунка пропущен обязательный согласно
стандартам HTML5 атрибут alt.
У HTML-валидатора есть еще одна полезная функция: по завершении
проверки он показывает, сколько времени было потрачено на загрузку вашей
страницы.
Если ошибок нет, валидаторы сообщат вам об этом. Любопытно заметить,
что о безупречности HTML-кода вы получите простое текстовое подтвержде-
ние. А вот качественную таблицу стилей Консорциум Всемирной паутины
предлагает отметить специальным знаком — что-то вроде знака качества, кото-
рый вам будет предложено разместить на странице сайта (по крайней мере так
было на момент написания книги).
Естественно, что разметка и таблицы стилей наших файлов в обязатель-
ном порядке проверялись в этих валидаторах. Результаты такой проверки вы
можете видеть на рисунках 4.2.1 и 4.2.2.
Кстати, совет на будущее. Есть немало заказчиков, которые не примут го-
товый «продукт», пока досконально не проверят, что именно вы им сделали.
Так что чем строже вы оцениваете свою работу, чем чище ваш код, тем больше
вероятность написать качественный сценарий с первого раза и не тратить время
на исправления и переделки. В идеале код должен быть совершенно чистым и
не содержать ни единой ошибки или нарушения стандартов!
Что касается валидатора JavaScript, то здесь ситуация несколько иная. Та-
ких валидаторов много. Автор опробовал несколько и выбрал из них вариант, в
котором реализован самый строгий подход к оценке кода. Вот его адрес: вали-
датор JavaScript — https://beautifytools.com/javascript-validator.php.
Он позволяет вставить в специальное текстовое поле ваш код, после чего
сразу, без нажатия каких-либо кнопок, начинается проверка скрипта. Един-
ственное неудобство этого валидатора, обнаруженное на момент написания
книги, — сообщения об ошибках, предупреждения и рекомендации он выдает в
общем списке, не выделяя пункты этого списка по степени важности.
38
Рис. 4.2.1
Проверка кода одного из файлов в HTML-валидаторе. Как видите, ошибок нет
Рис. 4.2.2
Проверка таблицы стилей одного из файлов в CSS-валидаторе.
Как видите, и здесь ошибок нет
Думаю, читатели уже догадываются, что все сценарии проекта, написан-
ные на JavaScript, были проверены в данном валидаторе. На момент написания
книги отклонений от стандартов языка и нарушений синтаксиса в сценариях
не было (рис. 4.2.3).
Особенность всех упомянутых валидаторов в том, что они находят все
ошибки в разметке, в таблицах стилей, в коде программ, в том числе пропущен-
ные символы, опечатки (но не в обычном тексте), необъявленные переменные
и т. д. Понятно, что задача хорошего программиста — исправить эти ошибки и
получить идеально чистый и правильный код. Что и было сделано автором.
39
Автор пытался тестировать и код PHP, но, хотя PHP-валидаторы суще-
ствуют, ни одного надежного на просторах Сети обнаружить не удалось.
Рис. 4.2.3
Проверка одного из сценариев. И опять ни одной ошибки
Рис. 4.3.1
Выбор кодировки для файла
40
5. СТРУКТУРА ПРОЕКТА
Прежде чем начать детальное рассмотрение проекта, разберемся с его
«комплектующими».
Напомню, что архив с полным набором всех компонентов находится по
адресу: https://editjs.ru/CMS.zip.
Архив состоит из 3 каталогов:
1) htdocs — содержит «чистую» CMS с набором установок по умолча-
нию, которые разработчик меняет в процессе конструирования сайта;
2) htdocs_1 — CMS с готовым вариантом сайта, на примере которого мы
будем рассматривать принцип действия системы;
3) htdocs_2 — практически аналогичный сайт, отличающийся от приве-
денного выше некоторыми настройками размеров блоков.
По сути, ресурсы из htdocs_1 и htdocs_2 демонстрируют один и тот же сайт,
разница в положении меню: в первом случае оно горизонтальное, во втором — вер-
тикальное.
41
5.2. Сайт
Итак, часть файлов из архива образуют структуру сайта, а другая часть —
системы управления. Сначала выясним, как взаимодействуют файлы, необхо-
димые для работы сайта.
«Скелет» любой страницы — HTML-код с разметкой (рис. 5.2.1). Непо-
средственно в теле документа прописаны все его элементы, кроме:
— основного содержания;
— рекламы;
— нижнего блока;
— таблицы стилей;
— сценариев на JavaScript (они необходимы для реализации ряда функ-
ций сайта).
Созданием разметки на странице управляет оболочка, написанная на PHP.
Рис. 5.2.1
Взаимодействие файлов сайта
Таблица стилей и сценарии добавляются в HTML-код в процессе загрузки
документа, минуя «посредников». А вот основное содержание, реклама и со-
держание нижнего блока вставляются с помощью PHP-оболочки из соответ-
ствующих txt-файлов. В PHP-коде предусмотрен механизм определения, какой
контент должен быть загружен для той или иной страницы.
У оболочки есть еще одна функция: проверять, соответствует ли адрес в
строке запроса адресу реально существующей страницы. Если искомая страни-
ца отсутствует, то никаких предупреждений не выводится, а просто загружает-
ся главная страница.
5.3. CMS
Как вы уже поняли, структура сайта довольно простая, соответственно
объем кода для обслуживания его страниц в несколько раз меньше, чем объем
кода системы управления. Ее структура показана на рисунке 5.3.1.
Вход в CMS и вывод меню обеспечивает один и тот же файл — cms.php.
Сначала администратор видит чистую страницу с текстовым полем для пароля.
После его ввода выполняется проверка, а затем, если пароль верный, открыва-
ется страница меню системы управления. Далее, когда необходимо перейти
42
в один из разделов, пароль вместе с запросом методом POST отправляется со-
ответствующему файлу. Здесь он вновь проверяется, после чего загружается
необходимая страница.
В этом месте сделаем небольшое отступление и поясним, что происходит,
если в систему пытается проникнуть злоумышленник, который знает структуру
файлов CMS. Во-первых, попытка передать пароль методом GET в теле запроса
окончится неудачей. Во-вторых, если недоброжелатель создал нужную форму и
отправил ее методом POST в качестве запроса к любому файлу вашей системы
управления (подчеркиваем — к любому), то он столкнется с защитой в виде
обязательной проверки пароля. Правда, реакция на попытку несанкциониро-
ванного использования файлов CMS может быть разной. Об этом мы погово-
рим в дальнейшем.
Рис. 5.3.1
Структура системы управления
Вернемся к теме. Основное меню CMS составляют 6 разделов.
1. Конструктор сайта. Его задача — компоновка блоков страниц, установ-
ка их размеров, выбор цвета фонов.
2. Специальные настройки. Здесь вы закачиваете необходимые для ди-
зайна сайта изображения, удаляете лишние, а также фиксируете адрес элек-
тронной почты администратора — именно на нее будут приходить сообщения
от посетителей.
3. Замена пароля. Все экземпляры CMS поставляются с паролем admin.
Естественно, его надо заменить на придуманный вами.
4. Список страниц. Тут вы видите, какие страницы существуют в вашем
проекте, добавляете новые, удаляете старые. Только из данного раздела вы мо-
жете перейти в режим редактирования той или иной страницы (в раздел «Ре-
дактор страниц»).
5. Добавление фото. Обеспечивает добавление, просмотр, удаление изоб-
ражений, которые администратор размещает на страницах сайта.
43
6. Добавление файлов. В этом разделе добавляются и удаляются файлы,
доступ к которым владелец ресурса хочет предоставить посетителям. Это могут
быть документы в формате doc, rtf, xl, pdf, txt и др.
В разделе 5.1 мы уже коротко прокомментировали состав компонентов
сайта и системы управления. Как вы уже поняли, сайт и каждый из разделов
меню управляется не одним, а несколькими файлами. Структуру их взаимодей-
ствия, принципы работы, особенности выполнения программного кода нам
предстоит выяснить в последующих главах.
44
6. ВХОД И ГЛАВНАЯ СТРАНИЦА CMS
Вы уже переместили систему управления на локальный хостинг. Посмотрели
вариант простого сайта, сделанного автором в демонстрационных целях. Теперь
пора разбираться, как и с помощью чего создаются этот и любой другой сайты.
Откройте браузер и наберите в строке адреса http://localhost/cms.php. Вы
окажетесь на странице входа в систему с полем для ввода пароля.
Для эксперимента наберите адрес другого раздела, например добавления
фотографий: http://localhost/photo.php. Вы вновь увидите поле для ввода пароля.
Эти примеры подтверждают уже изложенный факт — без знания пароля в
систему не войти. С правил входа мы и начнем изучение CMS.
Доступ в систему управления обеспечивают следующие файлы:
— cms.php — файл, создающий форму ввода пароля и главную страницу
CMS;
— set/passw.php — файл хранения пароля;
— set/tab.php — таблица шифрования;
— css/cms.css — определяет дизайн главной страницы CMS;
— css/every.css — определяет внешний вид вспомогательного меню на
всех страницах системы управления.
Последняя таблица стилей одинакова для всех разделов CMS, поэтому в
дальнейшем мы не станем упоминать о ней. Разбирая код, вы неоднократно
увидите вот такой адрес в заголовочных частях документов:
Рис. 6.1.1
Вход в систему управления
45
Способ первый — хранить пароль в файле с расширением .php. Он нахо-
дится в папке set, называется passw.php, а его содержимое выглядит так:
<?php
tiТоjR3Vr14wylIFS0uq
<?php
if(isset($_POST['pas']) && strlen($_POST['pas'])>4
&& strlen($_POST['pas'])<11)
{
...
}
else
echo '...
<form method="POST" action="cms.php">
<p id="passw"><input type="password"
name="pas" minlength="5" maxlength="10"
id="pas"></p>
</form>';
?>
else
echo '...
<form method="POST" action="cms.php">
46
<p id="passw"><input type="password"
name="pas" minlength="5" maxlength="10"
id="pas"></p>
</form>';
Подчеркну, что когда вы набираете в браузере адрес
http://localhost/cms.php, в этом запросе пароль отсутствует, поэтому браузер
как раз и выводит данную форму на страницу. Вот теперь мы и вводим пароль.
Идем дальше. Считаем, что первый этап проверки был успешным. Сле-
дующий шаг — сравнение введенного пароля с зашифрованным, хранящимся в
файле passw.php. Для этого загружаем таблицу шифрования, которая находит-
ся в папке set в файле tab.php:
include 'set/tab.php';
Вот ее код:
<?php
$ar = ['A' => 'сеN0',
'a' => 'tiТ',
...,
'9' => 'ibqCE'];
а затем в цикле
47
Если сравнение было успешным, выводим содержимое страницы:
if($sum==$passw[1])
{
echo '...';
}
Введен неверный пароль? Вновь загружаем в браузер форму для его по-
вторного ввода:
else
echo '...
<form method="POST" action="cms.php">
<p id="passw"><input type="password"
name="pas" minlength="5" maxlength="10"
id="pas"></p>
</form>';
<div id="basis">
...
</div>
<div id="bas">
<a href="index.php" target="_blank">
<img src="draw/site.png" id="site" alt="..."></a>
<span id="system">Система управления сайтом</span>
<form method="POST" action="cms.php">
<input type="hidden" name="pas"
value="'; echo $pas; echo '">
<input type="image" src="draw/home.png" id="home"
alt="..." title="...">
</form>
</div>
В данном меню всего два пункта.
48
1. Просмотр сайта — ссылка в левом верхнем углу в виде рисунка с изоб-
ражением монитора. Если щелкнуть по нему, то в новой вкладке загрузится
главная страница сайта.
2. Возврат на главную страницу системы управления — ссылка в правом
верхнем углу в виде картинки с изображением крыш домов. Клик на ней воз-
вращает администратора в меню CMS.
Рис. 6.2.1
Меню системы управления
Как видно из приведенного ранее кода, рисунок с крышами на самом деле
является кнопкой отправки формы, состоящей всего из одного скрытого поля с
паролем:
49
<input type="image" src="draw/designer.png" alt="..."
title="...">
<br>Конструктор сайта
</form>
</div>
...
<div id="files" class="mainmenu">
<form method="POST" action="file.php">
<input type="hidden" name="pas"
value="'; echo $pas; echo '">
<input type="image" src="draw/files.png" alt="..."
title="...">
<br>Добавление файлов
</form>
</div>
Картинки служат кнопками отправки форм тому или иному файлу с про-
граммой соответствующего блока. Как и в предыдущем случае, в каждой форме
всего одно скрытое поле с паролем. Адреса файлов указываются в атрибутах
action-форм. Данные опять же передаются методом POST.
Кликнув на любой из шести основных картинок, вы попадаете в соответ-
ствующий раздел системы управления. О них сейчас и пойдет речь.
50
7. ЗАМЕНА ПАРОЛЯ
Рассмотрение функций разделов мы начнем не в порядке их расположе-
ния в меню, а с того блока, к которому надо обратиться в первую очередь. Речь
идет о замене стандартного пароля. Это необходимо сделать в целях обеспече-
ния безопасности вашего экземпляра CMS.
На всякий случай напомним, что в системе заданы следующие требова-
ния к незашифрованному паролю:
— он должен содержать от 5 до 10 знаков;
— в нем можно использовать только латинские буквы (в любом регистре)
и цифры от 0 до 9.
Также напомним, о чем говорилось в предыдущей главе. Порядок ваших
действий должен быть такой:
1) поменяйте наборы символов в таблице шифрования;
2) в соответствии с ее новыми значениями вручную зашифруйте пароль
admin;
3) запишите получившийся результат во второй строке файла
set/passw.php и не нажимайте после пароля «Enter»!
Теперь можно входить в систему управления и придумывать новый пароль.
Программный блок замены пароля объединяет следующие файлы:
— pas.php — формирует страницу замены пароля в системе управления;
— css/pas.css — определяет дизайн страницы;
— js/pas.js — формирует Ajax-запрос на перезапись пароля и обрабаты-
вает ответ серверной программы;
— newpas.php — программа записи пароля;
— set/passw.php — файл хранения пароля.
Заметим, что все операции передачи данных серверным программам во
всех блоках системы управления происходят в фоновом режиме по технологии
Ajax. В дальнейшем автор не станет упоминать об этом факте, считая, что чита-
тели запомнили данную информацию.
51
<input type="button" id="but" value="Записать">
</form>
Рис. 7.1.1
Страница замены пароля
addEventListener("load", function()
{
document.getElementById("but").
addEventListener("click", pas);
...
});
addEventListener("load", function()
{
// Обработчики, переменные, функции
...
});
a-z
52
и цифры
\d
[a-z\d]+
/^[a-z\d]+$/
/^[a-z\d]+$/i
let rv=/^[a-z\d]+$/i;
let np=document.getElementById("newpas");
let but=document.getElementById("but");
function pas()
{
...
}
return false;
53
Здесь мы опять сталкиваемся с приемом, который используется во всех
блоках системы управления. Любые сообщения от любого сценария мы всегда
выводим на кнопку, которая запускает данный сценарий. Так что привыкайте к
этому.
Рис. 7.2.1
Программа сообщает, что пароль слишком короткий
Второй этап — проверка введенного пароля на соответствие регулярному
выражению:
if(rv.test(np.value)==false)
{
...
}
Найдены отклонения от шаблона? Сообщаем об этом администратору
(рис. 7.2.2) и прерываем выполнение функции:
but.value="НЕДОПУСТИМЫЕ СИМВОЛЫ В ПАРОЛЕ !";
return false;
Рис. 7.2.2
Использовав в начале пароля кириллическую букву «я», мы допустили ошибку
Проверка была успешной? Переходим к третьему шагу — отправке дан-
ных. Для этого создаем новый объект данных из формы:
let dt=new FormData(document.forms.dat);
Формируем запрос:
re.open("POST", "newpas.php", true);
54
и отправляем его серверной программе:
re.send(dt);
$let=str_split($_POST['pas']);
$sum='';
$passw=file('set/passw.php');
if($sum==$passw[1])
{
...
}
else
echo '2';
}
else
echo '2';
55
Если проверка завершается успешно, происходит шифрование нового па-
роля уже знакомым нам способом:
$let=str_split($_POST['newpas']);
$sum='';
for($t=0; $t<count($let); $t++)
$sum.=$ar[$let[$t]];
Рис. 7.2.3
Сообщение об успешной записи нового пароля
56
8. СПЕЦИАЛЬНЫЕ НАСТРОЙКИ
И опять рассмотрение блоков системы продолжится не по порядку их
расположения в основном меню, а в последовательности, которая упрощает по-
нимание функциональности CMS. На этот раз мы рассмотрим страницу «Спе-
циальные настройки».
К специальным настройкам (их можно еще назвать предварительными)
относятся:
— функция закачки изображения, которое необходимо в дизайне сайта;
— функция просмотра закачанных рисунков и удаление лишних;
— функция записи адреса электронной почты администратора.
Эти действия обеспечиваются следующим набором файлов:
— sett.php — формирует раздел специальных настроек в системе управ-
ления;
— css/sett.css — определяет дизайн страницы;
— js/sett.js — формирует запросы на фиксацию настроек и обрабатывает
ответы серверных программ;
— newsett.php — программа загрузки картинок, используемых в дизайне
страниц сайта;
— delsett.php — файл удаления лишних картинок;
— newmail.php — файл записи адреса электронной почты администратора;
— set/email.txt — файл хранения адреса электронной почты администратора.
57
Как видите, это обычная форма с указанием enctype, полем file и скры-
тым полем hidden с паролем, который проверяется скриптом записи, чтобы
убедиться в «законности» поступающих данных. Обратите внимание: в име-
ни загружаемого фото должны быть только латинские буквы и цифры без
пробелов!
Рис. 8.1.1
Раздел специальных настроек
Форма удаления лишних снимков:
<form method="POST" id="delp" name="dat2">
Удалить фото: <input id="photo" name="photo">
<input type="hidden" name="pas"
value="'; echo $pas; echo '">
<input type="button" id="but"
value="Посмотреть / Выбрать">
<input type="button" id="but2" value="Удалить">
</form>
<div id="list_d">
<img src="draw/close.png" id="list_i" alt="Закрыть"
title="Закрыть">
<p id="p_list">';
58
$opdir=opendir("pict");
while($redir=readdir($opdir))
{
if(strpos($redir, "."))
echo '<img class="roster" src="pict/'.$redir.'"
id="'.$redir.'" alt="Фото">';
}
closedir($opdir);
echo '</p></div>
Открываем директорию
$opdir=opendir("pict");
и в цикле
while($redir=readdir($opdir))
{
...
}
Рис. 8.1.2
Вкладка просмотра и удаления изображений
К сожалению, в список попадут такие элементы, как точка и две точки
(. и ..), которые обозначают текущий и вышестоящий каталоги.
Чтобы преодолеть эти проблемы, устроим проверку:
if(strpos($redir, "."))
...
59
Операция
strpos($redir, "."))
closedir($opdir);
$mai=file('set/email.txt');
$mai=file('set/email.txt');
60
учитывать их существование не имеет смысла). Максимальная длина e-mail,
установленная в системе, 50 знаков.
document.getElementById("but1").
addEventListener("click", cont);
if(document.getElementById("newfoto").value=="")
{
but1.value="ВЫ НЕ ЗАГРУЗИЛИ ИЗОБРАЖЕНИЕ !";
return false;
}
else
{
let dt=new FormData(document.forms.dat1);
let re=new XMLHttpRequest();
re.open("POST", "newsett.php", true);
re.send(dt);
re.addEventListener("load", show);
}
61
Но теперь функция show будет несколько сложнее:
function show()
{
let ans=this.responseText;
let arans=ans.split(";");
if(arans[0]==1)
{
...
}
if(arans[0]==2)
...
...
}
let ans=this.responseText;
let arans=ans.split(";");
if(arans[0]==2)
but1.value="НЕКОРРЕКТНЫЕ ДАННЫЕ !";
62
document.getElementById("p_list").
insertAdjacentHTML("beforeend", point);
setTimeout(()=>{but.value="Записать";}, 2000);
if(($_FILES['newfoto']['error']==0) &&
(strpos($_FILES['newfoto']['type'], 'image')===0))
{
...
}
else
echo '2';
echo '1;'.basename($_FILES['newfoto']['name']);
63
});
document.getElementById("p_list").
addEventListener("click", function(ev)
{
if(ev.target.tagName=="IMG")
{
let pho=ev.target.src.split('pict/');
document.getElementById("photo").value=pho[1];
document.getElementById("list_d").
style.visibility="hidden";
}
});
let pho=ev.target.src.split('pict/');
document.getElementById("photo").value=pho[1];
document.getElementById("list_d").
style.visibility="hidden";
64
8.4. Удаление фото
Этот процесс «доверен» серверной программе delsett.php. Она очень про-
стая. За проверкой пароля следует проверка заполнения поля photo:
if(isset($_POST['photo']) &&
strlen($_POST['photo'])>3)
{
...
}
else
echo '2';
unlink('pict/'.$_POST['photo']);
echo '1';
document.getElementById("but2").
addEventListener("click", del);
let but2=document.getElementById("but2");
function del()
{
if(document.getElementById("photo").value.length<3)
{
but2.value="ВЫ НЕ ВЫБРАЛИ ИЗОБРАЖЕНИЕ !";
return false;
}
else
{
if(window.confirm("Вы действительно хотите
удалить это фото?")==true)
{
let dt=new FormData(document.forms.dat2);
let re=new XMLHttpRequest();
re.open("POST", "delsett.php", true);
re.send(dt);
re.addEventListener("load", see);
}
65
}
}
function see()
{
let ans=this.responseText;
if(ans==1)
{
but2.value="ИЗОБРАЖЕНИЕ УДАЛЕНО !";
let el=document.getElementById("photo").value;
document.getElementById(el).remove();
}
if(ans==2)
but2.value="НЕКОРРЕКТНЫЕ ДЕЙСТВИЯ !";
setTimeout(()=>{but2.value="Удалить";}, 2000);
}
let but3=document.getElementById("but3");
66
Проверяем длину электронного адреса:
if(np.value.length<8 || np.value.length>50)
{
but3.value="НЕКОРРЕКТНАЯ ДЛИНА E-MAIL !";
return false;
}
То есть первый символ — это только буква. Затем идет некоторое коли-
чество произвольных символов из тех, что разрешены, — буквы, цифры, точка,
дефис:
[a-z\d.-]+
Знак + означает, что символов может быть более одного. Наконец, завер-
шающий символ — буква или цифра:
[a-z\d]
67
[a-z\d-]+
[a-z\d]
\.
[a-z]{2,13}
/^[a-z][a-z\d.-]+[a-z\d]@[a-z\d][a-z\d-]+
[a-z\d]\.[a-z]{2,13}$/i;
setTimeout(()=>{but3.value="Записать";}, 2000);
}
68
9. САЙТ
В этой главе мы отступим от последовательного описания устройства
CMS. Автор посчитал, что до изучения следующего модуля — конструктора —
было бы неплохо сначала выяснить на конкретных примерах, какие сайты поз-
воляет разрабатывать наша система. Этим мы сейчас и займемся.
Думаю, не имеет смысла долго объяснять, что задача проекта — не впе-
чатлить читателей навороченным дизайном и сложным контентом, а рассказать,
как можно создавать, менять и редактировать этот контент. Поэтому автор ре-
шил в основу проекта положить создание максимально простого сайта с макси-
мально простой структурой и максимально простым дизайном. Каждая страни-
ца ресурса, опять же для простоты, имеет фиксированную ширину (чтобы не
усложнять дело адаптивной версткой) и включает пять компонентов (четыре из
них — с настраиваемой шириной):
— заставка в самой верхней части страницы (заставка создается тем или
иным рисунком);
— блок меню с элементами навигации по страницам ресурса;
— контейнер для основного содержания;
— блок рекламы;
— нижний блок (он единственный обладает фиксированной шириной —
100%).
Хотя два последних блока имеют строгое название, размещать в них
можно любую информацию. Нужно только учитывать один важный момент:
содержимое этих блоков одинаково для всех страниц сайта.
В создании и дизайне страниц по умолчанию участвуют сразу 9 файлов:
— index.php — файл шаблона страниц сайта;
— css/index.css — определяет дизайн сайта;
— js/index.js — управляет просмотром фотографий;
— cont.php — отправляет данные формы со страницы «Контакты»;
— js/cont.js — проверяет заполнение формы и передает запрос программе
отправки данных;
— content/cont.txt и content/index.txt — текстовые файлы с данными
страницы «Контакты» и главной страницы;
— set/advert.txt — файл хранения рекламной информации;
— set/footer.txt — файл хранения контента нижнего блока.
9.1. Варианты компоновки страниц
Конструктор позволяет создавать четыре основных варианта дизайна и
еще несколько максимально упрощенных.
Любая страница сайта включает 6 блоков.
1. Заставка в верхней части страницы. В качестве нее предусмотрено ис-
пользовать изображение произвольной высоты и шириной, строго равной ши-
рине границ страницы (не путайте с шириной окна браузера!).
69
2. Все остальные блоки помещаются во flex-контейнере, который, меняя
позиционирование, можно перемещать в вертикальном направлении. В том
числе «заезжая» на заставку. Последний вариант можно увидеть в следующем
разделе на рисунке 9.2.1. Или загрузив на локальный хостинг содержимое пап-
ки htdocs_1 с первым демонстрационным сайтом.
3. Меню. Оно может быть горизонтальным или вертикальным. Вариант
настраивается по вашему желанию путем изменения размеров блоков, входя-
щих во flex-контейнер.
4. Основное содержание — контейнер, предназначенный для размещения
основных текстов, рисунков, таблиц и т. д.
5. Рекламный блок. Название условное, так как в этой области можно по-
мещать не только рекламу, но и вообще любой контент, который одинаков для
всех страниц.
6. Нижний блок. Обычно служит для различной дополнительной инфор-
мации, например копирайта, адреса электронной почты. Но, как и в предыду-
щем блоке, здесь может быть любая информация, одинаковая для всех страниц.
Еще раз подчеркну: основное содержание наполняется отдельно для каж-
дой страницы. Контент нижнего блока и рекламного остается одним и тем же
на всех страницах.
Перейдем к вариантам компоновки. Они показаны ни рисунке 9.1.1.
Рис. 9.1.1
Варианты компоновки блоков страницы
70
Первый вариант — один из наиболее распространенных на просторах Ин-
тернета. Меню — горизонтальное. Под ним в одном ряду основное содержание
и рекламный модуль. Последним, как и положено, стоит нижний блок.
Второй вариант показывает вертикальное меню слева, основное содержа-
ние — посередине, реклама — справа. Нижний блок под ними.
Третья компоновка — построение всех модулей по вертикали.
В последней — четвертой — компоновке меню и основное содержание
находятся в одном ряду. Под ними сначала реклама, а дальше нижний блок.
Какими приемами достигаются подобные компоновки, мы рассмотрим в
следующей главе, когда перейдем к рассмотрению конструктора. Также в сле-
дующей главе автор пояснит, как можно исключить рекламу и нижний блок из
структуры сайта, сделав его дизайн совсем простым.
Обращаю ваше внимание: изменение компоновки достигается без ручной
правки файлов, а только стандартными настройками в конструкторе.
$adr="index";
if(isset($_GET["a"]))
{
...
}
71
Рис. 9.2.1
Один из множества возможных вариантов страницы сайта
Если не передан, то загружаем главную страницу, так как значение пере-
менной $adr не изменилось.
Если параметр передан, присваиваем его значение новой переменной
$test_adr:
if(isset($_GET["a"]))
{
$test_adr=$_GET["a"];
...
72
}
$opdir=opendir("content");
while($redir=readdir($opdir))
{
...
}
closedir($opdir);
$adr=$test_adr;
break;
Рис. 9.2.2
Еще один вариант компоновки того же сайта
73
В конце процедуры открываем текстовый файл, идентификатор которого
мы только что определили, и построчно считываем этот файл в массив:
$page='content/'.$adr.'.txt';
$soder=file($page);
<?php
$adr='index';
if(isset($_GET['a']))
{
$test_adr=$_GET['a'];
$opdir=opendir('content');
while($redir=readdir($opdir))
{
if($test_adr.'.txt'==$redir)
{
$adr=$test_adr;
break;
}
}
closedir($opdir);
}
$page='content/'.$adr.'.txt';
$soder=file($page);
?>
<meta name="description"
content="<?php echo rtrim($soder[3]); ?>">
74
Завершаем процесс загрузкой таблицы стилей и сценария для просмотра
снимков:
<?php
if($adr=='cont')
echo '<script src="js/cont.js"></script>';
?>
<div id="basis">
...
</div>
<div id="header"></div>
Второй — flex-контейнер:
<div id="divfl">
...
</div>
<nav id="menu">
...
</nav>
75
Его формирование — довольно непростой процесс. Сначала мы объявля-
ем пустой массив, в который предстоит занести данные кнопок меню:
$srtar=array();
$opdir=opendir('content');
...
closedir($opdir);
и в цикле
while($redir=readdir($opdir))
{
if(strpos($redir, '.'))
{
...
}
}
$name=file('content/'.$redir);
if(rtrim($name[1])=='ДА')
$srtar[$name[0]]=
'<a href="index.php?a='.$rep.'"
class="tdn"><h4 class="lin">'.
$name[2].'</h4></a>';
<h4 class="lin">'.$name[2].'</h4>
$newar=ksort($srtar);
Чем ниже цифра в рейтинге, тем выше в списке меню окажется страница.
По умолчанию рейтинг 1 имеет главная страница, значит, она будет показы-
ваться первым пунктом меню. Подробнее о рейтингах вы узнаете в главе 13.
Печатаем меню, в цикле проходя по значениям ключей:
<div id="content">
<?php
echo $soder[5];
?>
</div>
<div id="advert">
<?php
$page='set/advert.txt';
$soder=file_get_contents($page);
echo $soder;
?>
</div>
<div id="footer">
<?php
$page='set/footer.txt';
$soder=file_get_contents($page);
echo $soder;
?>
</div>
Наличие свойства
z-index: 1
z-index: 2
78
нера могут «наползать» на заставку. Подобный случай мы видели в предыду-
щем разделе на рисунке 9.2.1.
Стили меню тоже заданы таким образом, чтобы его внутренние элементы
располагались слева направо в линию, но при переполнении контейнера сме-
щались вниз на следующую строку:
#menu {display: flex; flex-wrap: wrap;
justify-content: center; align-content: flex-start;
width: ...; margin-bottom: ...; margin-right: ...;
font-family: ...; font-size: ...;}
80
служит контейнером для увеличенного рисунка:
Рис. 9.4.1
Просмотр одной из фотографий страницы
Для вставки данного фрагмента кода автор выбрал место сразу после от-
крывающего тега body:
...
<body>
<div id="bas"></div>
<div id="view">
<img id="pict" src="img/net.jpg" alt="Фото">
</div>
<div id="basis">
...
81
Сценарий index.js из папки js подключаем в заголовочной части доку-
мента (файла index.php) следующим образом:
<script src="js/index.js"></script>
addEventListener("load", function()
{
...
});
Для сокращения кода, в котором несколько раз происходят обращения к
одним и тем же компонентам, создадим три переменные:
let view=document.getElementById("view");
let bas=document.getElementById("bas").style;
let pict=document.getElementById("pict");
document.getElementById("content").
addEventListener("click", function(ev)
{
...
});
let sc=window.pageYOffset;
83
Наполнение страницы «Контакты» представлено на рисунке 9.5.1. Форма
имеет три поля — «Ваше имя», «Телефон или e-mail» и «Сообщение», а также
кнопку «Отправить». Если какое-то поле оставить незаполненным, то появляет-
ся соответствующее предупреждение. Причем выводится оно, как и в системе
управления, прямо на кнопку «Отправить», заменяя ее изначальный текст
(рис. 9.5.2).
Рис. 9.5.1
Страница «Контакты»
Отправка заявки выполняется с помощью технологии Ajax. То есть в
браузере остается та же страница. В это время сценарий из файла cont.js снача-
ла проверяет данные, а потом отправляет запрос программе cont.php. Там дан-
ные проверяются еще раз, после чего происходит отправка информации адми-
нистратору по e-mail. На последнем этапе программа cont.php возвращает фай-
лу cont.js отчет об ошибке, если была попытка отправить запрещенные данные
(рис. 9.5.3). Список запрещенных символов введен, чтобы защитить программу
от недоброжелателей. Если данные успешно прошли все проверки, то на по-
следнем шаге сценарий из cont.js выводит на страницу подтверждение о полу-
чении заявки (и опять на кнопку отправки данных — рис. 9.5.4).
Рис. 9.5.2
Предупреждение, если заполнены не все поля
84
Рис. 9.5.3
Предупреждение, если введены запрещенные символы. В данном случае
в поле «Сообщение» есть запрещенный знак <
Рис. 9.5.4
Подтверждение успешной отправки сообщения
Форма отправки сообщения находится в файле content/cont.txt. Выглядит
она очень просто:
<form method="POST" name="dat">
<table ...>
<tr>
<td ...>Ваше имя:</td>
<td><input type="text" id="nam" name="nam"
minlength="2" maxlength="50" ...></td>
</tr>
<tr>
<td ...>Телефон или e-mail:</td>
<td><input type="text" id="con" name="con"
minlength="8" maxlength="50" ...></td>
</tr>
<tr>
<td ...>Сообщение:</td>
<td><textarea id="tex" name="tex"
85
minlength="10" maxlength="1000" ...></textarea></td>
</tr>
<tr>
<td> </td>
<td><p><input type="button" value="Отправить"
id="but" ...></p></td>
</tr>
</table>
</form>
86
Обнаружив, что данное поле пустует, выводим предупреждение «ВЫ НЕ
ВВЕЛИ ИМЯ !» и прерываем отправку данных. Напомню, что здесь мы вновь
использовали креативное решение — все предупреждения выводятся непосред-
ственно на кнопку but вместо ее первоначальной надписи «Отправить»:
but.value="ВЫ НЕ ВВЕЛИ ИМЯ !";
87
Также устанавливаем, что после загрузки ответа должна запускаться
функция show:
re.addEventListener("load", show);
if((strlen($t1)<2) || (strlen($t2)<8) ||
(strlen($t3)<10))
echo '2';
else
{
...
}
Затем максимальное:
if((strlen($t1)>50) || (strlen($t2)>50) || (strlen($t3)>1000))
echo '3';
else
{
...
}
88
(strpos($t3, 'return')) ||
(strpos($t3, 'href')))
echo '3';
else
{
...
}
echo '1';
function show()
{
let re=document.getElementById("but");
let ans=this.responseText;
if(ans==1)
re.value="СООБЩЕНИЕ ОТПРАВЛЕНО !";
if(ans==2)
re.value="ЗАПОЛНЕНЫ НЕ ВСЕ ПОЛЯ !";
if(ans==3)
re.value="НЕКОРРЕКТНЫЕ ДАННЫЕ !";
setTimeout(()=>{but.value="Отправить";}, 3000);
}
setTimeout(()=>{but.value="Отправить";}, 3000);
89
10. КОНСТРУКТОР САЙТА
Сейчас мы обсудим один из самых важных модулей, который отвечает за
дизайн сайта. Он называется конструктором. В работе этого модуля участвуют
следующие файлы:
1) design.php — формирует страницу конструктора;
2) css/design.css — определяет вид страницы;
3) js/design.js — управляет переключением вкладок с параметрами и со-
здает запрос к программе записи данных;
4) newdesign.php — записывает настройки дизайна в соответствующие
файлы;
5) css/index.css — сюда записываются стили, установленные для сайта в кон-
структоре;
6) set/design.txt — хранит параметры дизайна (назначение объясним позже).
Рис. 10.1.1
Страница конструктора
90
Руководствуясь этими подсказками, вы упростите себе выбор настроек в
соответствии со своими пожеланиями.
Второй элемент — кнопка записи, нажатие которой фиксирует выбранные
настройки.
Третий элемент — вкладки, в которых необходимо ввести нужные значения.
Сообщения, подтверждающие успешную запись информации, выводятся
на кнопке «Записать».
10.2. Блоки
Код страницы, образованной программой design.php, состоит из двух
блоков: иллюстраций вариантов дизайна и вкладок с настройками.
HTML-код иллюстраций:
<img src="draw/struct.jpg" id="struct"
alt="..." title="...">
<img src="draw/struct_2.jpg" id="struct2"
alt="..." title="...">
document.getElementById("struct").style.visibility=
"hidden";
document.getElementById("struct2").style.visibility=
"visible";
document.getElementById("struct").style.visibility=
"visible";
document.getElementById("struct2").style.visibility=
"hidden";
91
Данные дизайна хранятся в двух файлах. Первый — css/index.css. Его мы
уже комментировали. В этот фал записываются свойства элементов любой
страницы. Второй файл — set/design.txt — нужен для записи настроек в виде,
удобном для чтения модулем «Конструктор сайта». Чтобы не вычленять необ-
ходимые параметры из сложной таблицы стилей index.css, лучше хранить эти
же самые значения в дополнительном файле design.txt и загружать эти данные
при открытии страницы «Конструктор сайта».
CMS поставляется с настройками по умолчанию, которые и загружаются
в модуль после его первого запуска.
Вернемся к файлу design.php. Считываем текстовый файл design.txt:
$val=file('set/design.txt');
for($i=0; $i<count($val); $i++)
$val[$i]=rtrim($val[$i]);
...
<div id="maindiv">
...
</div>
<div id="menudiv">
...
</div>
<div id="subsdiv">
...
</div>
</form>
<div id="list_d">
<img src="draw/close.png" id="list_i" alt="Закрыть"
title="Закрыть">
<p id="p_list">';
$opdir=opendir("pict");
while($redir=readdir($opdir))
{
if(strpos($redir, "."))
echo '<img class="roster" src="pict/'.$redir.'"
92
id="'.$redir.'" alt="Фото">';
}
closedir($opdir);
echo '</p></div>
document.getElementById("bf5").
addEventListener("click", function()
{
document.getElementById("list_d").
style.visibility="visible";
});
document.getElementById("list_i").
addEventListener("click", function()
{
document.getElementById("list_d").
style.visibility="hidden";
});
document.getElementById("p_list").
addEventListener("click", function(ev)
{
if(ev.target.tagName=="IMG")
{
let pho=ev.target.src.split('pict/');
document.getElementById("f5").value=pho[1];
document.getElementById("list_d").
style.visibility="hidden";
}
});
10.3. Вкладки
Их три. «Основные настройки» — в этой вкладке шесть полей с главными
параметрами страницы. В «Меню» настраиваем положение и параметры кнопок
меню. «Содержание» — в этой вкладке устанавливаем настройки блока основ-
ного содержания, рекламы и нижнего.
Во вкладке основных настроек в качестве фото заставки выбирается ри-
сунок из имеющихся в папке pict. Код слоя с иллюстрациями, одинаковый для
многих модулей системы управления, мы уже посмотрели в предыдущем раз-
деле.
Ряд параметров — шрифты, выравнивание, наличие тени — выбирается
из выпадающих списков.
93
Установка цвета тех или иных элементов работает очень просто. Нажмите
кнопку открытия окна выбора цвета (на рис. 10.3.1 эта кнопка обозначена верх-
ней стрелкой). Определите требуемый тон, передвигая круглый ползунок по
цветовой шкале (обозначен нижней стрелкой). Перемещая круглый курсор
(обозначен средней стрелкой) по прямоугольнику палитры, выберите необхо-
димый оттенок. Нажмите кнопку «Выбрать» — и код цвета появится в соответ-
ствующем поле. Обратите внимание: в браузере Firefox вкладка выбора цвета
выглядит совершенно иначе, нежели аналогичные вкладки в других браузерах
(рис. 10.3.2).
Рис. 10.3.1
Выбор цвета текста или его фона
Рис. 10.3.2
Выбор цвета в браузере Firefox
Переключением вкладок управляет сценарий из файла design.js.
Регистрируем три обработчика кликов на вкладках:
document.getElementById("main").
addEventListener("click", func);
document.getElementById("menu").
94
addEventListener("click", func);
document.getElementById("subs").
addEventListener("click", func);
а остальные — на задний:
else
{
arst.zIndex="10";
ardivst.zIndex="20";
ardivst.visibility="hidden";
}
Благодаря этой программе происходит переключение вкладок с настройками.
95
10.4. Запись результата
Тут все идет стандартно — по «тропинке», неоднократно «проторенной»
в предыдущих сценариях и серверных скриптах.
После нажатия кнопки «Записать» отправляем запрос на сервер:
document.getElementById("but").
addEventListener("click", function()
{
let dt=new FormData(document.forms.dat);
let re=new XMLHttpRequest();
re.open("POST", "newdesign.php", true);
re.send(dt);
re.addEventListener("load", show);
});
$ret=0;
$inp="...";
if(file_put_contents('css/index.css', $inp))
echo $ret+=0.5;
В итоге код ответа — 1 (0.5 + 0.5).
96
Переменная $inp содержит полный список свойств и значений, записыва-
емых в таблицу стилей. Список этот весьма объемный, поэтому мы не стали
приводить его. Посмотрите файл newdesign.php.
На последнем этапе сценарий из файла design.js добавляет соответству-
ющий текст на кнопку «Записать»:
function show()
{
let re=document.getElementById("but");
let ans=this.responseText;
if(ans==1)
re.value="ЗАПИСАНО";
else
re.value="НЕ ЗАПИСАНО";
setTimeout(()=>{document.getElementById("but").
value="Записать";}, 2000);
}
Рис. 10.4.1
Подтверждение успешной записи настроек дизайна
97
11. ДОБАВЛЕНИЕ ФОТО
Будем считать, что вы уже завершили настройку дизайна будущего ре-
сурса. Но приступать к созданию и наполнению страниц еще рано. У нас пока
не загружены необходимые иллюстрации. К этому процессу мы сейчас и пе-
рейдем. Правда, рассказ будет достаточно короткий. Дело в том, что модуль за-
качки фотографий очень напоминает соответствующий модуль добавления и
удаления снимков, который мы рассматривали в главе 8. Поэтому обоснованно
сократим повествование. Скажем только, что в функционировании раздела до-
бавления фото принимают участие следующие пять файлов:
— photo.php — формирует раздел добавления и удаления снимков;
— css/photo.css — определяет дизайн страницы;
— js/photo.js — формирует запросы на закачку и удаление изображений,
а также отвечает за их просмотр;
— newphoto.php — программа загрузки картинок, используемых на страни-
цах сайта;
— delphoto.php — программа удаления лишних картинок.
Рис. 11.1.1
Страница добавления и удаления фото
HTML-код первой формы:
<form method="POST" id="newp" name="dat1"
enctype="multipart/form-data">
Добавить новое фото для страниц сайта:
98
<input type="file" id="newfoto" name="newfoto">
<input type="hidden" name="pas"
value="'; echo $pas; echo '">
<input type="button" id="but1" value="Добавить">
</form>
Эта разметка один в один повторяет то, что мы видели в разделе специ-
альных настроек. Даже имена полей совпадают.
Напомним: в имени загружаемого фото должны быть только латин-
ские буквы и цифры без пробелов!
Код второй формы:
<form method="POST" id="delp" name="dat2">
Удалить фото: <input id="photo" name="photo">
<input type="hidden" name="pas"
value="'; echo $pas; echo '">
<input type="button" id="but"
value="Посмотреть / Выбрать">
<input type="button" id="but2" value="Удалить">
</form>
<div id="list_d">
<img src="draw/close.png" id="list_i" alt="Закрыть"
title="Закрыть">
<p id="p_list">';
$opdir=opendir("img");
while($redir=readdir($opdir))
{
if(strpos($redir, "."))
echo '<img class="roster" src="img/'.$redir.'"
id="'.$redir.'" alt="Фото">';
}
closedir($opdir);
echo '</p></div>
document.getElementById("but1").
addEventListener("click", cont);
...
let but1=document.getElementById("but1");
99
В теле функции cont проверяем, загружен ли рисунок:
if(document.getElementById("newfoto").value=="")
{
but1.value="ВЫ НЕ ЗАГРУЗИЛИ ИЗОБРАЖЕНИЕ !";
return false;
}
else
{
...
}
let ans=this.responseText;
let arans=ans.split(";");
if(arans[0]==1)
{
but1.value="ИЗОБРАЖЕНИЕ ЗАГРУЖЕНО !";
...
}
if(arans[0]==2)
but1.value="НЕКОРРЕКТНЫЕ ДАННЫЕ !";
if(($_FILES['newfoto']['error']==0) &&
(strpos($_FILES['newfoto']['type'], 'image')===0))
{
...
}
else
echo '2';
100
— перезаписывает файл в место постоянного хранения:
move_uploaded_file($_FILES['newfoto']['tmp_name'],
'img/'.basename($_FILES['newfoto']['name']));
echo '1;'.basename($_FILES['newfoto']['name']);
101
...
let but2=document.getElementById("but2");
unlink('img/'.$_POST['photo']);
echo '1';
102
12. ДОБАВЛЕНИЕ ФАЙЛОВ
Этот блок системы тоже имеет много общего с разделом специальных
настроек и, соответственно, с функционалом добавления фото. Поэтому про-
цессу загрузки файлов уделим минимальное внимание.
В работе блока участвуют следующие компоненты:
— file.php — формирует раздел добавления и удаления файлов;
— css/file.css — определяет дизайн страницы;
— js/file.js — формирует запросы на закачку и удаление файлов;
— newfile.php — программа загрузки новых файлов;
— delfile.php — программа удаления лишних файлов.
Закачанные файлы добавляются в папку file.
Рис. 12.1.1
Страница загрузки и удаления файлов
На странице две формы: добавления файлов и удаления.
Первая форма нам уже хорошо знакома:
103
<form method="POST" id="newf" name="dat1"
enctype="multipart/form-data">
Добавить новый файл для страниц сайта:
<input type="file" id="newfile" name="newfile">
<input type="hidden" name="pas"
value="'; echo $pas; echo '">
<input type="button" id="but1" value="Загрузить">
</form>
$ident=0;
$opdir=opendir("file");
while($redir=readdir($opdir))
{
if(strpos($redir, "."))
{
...
}
}
closedir($opdir);
if($ident==0)
{
echo '<option selected value="'.$redir.'"
id="'.$redir.'">'.$redir.'</option>';
$ident=1;
}
else
echo '<option value="'.$redir.'"
id="'.$redir.'">'.$redir.'</option>';
104
Если идентификатор имеет начальное значение 0, то в качестве выбранного
будет пункт с именем первого файла:
$ident=1;
else
echo '<option value="'.$redir.'"
id="'.$redir.'">'.$redir.'</option>';
if($_FILES['newfile']['error']==0)
{
move_uploaded_file($_FILES['newfile']['tmp_name'],
105
'file/'.basename($_FILES['newfile']['name']));
echo '1;'.basename($_FILES['newfile']['name']);
}
else
echo '2';
function show()
{
let ans=this.responseText;
let arans=ans.split(";");
if(arans[0]==1)
{
but1.value="ФАЙЛ ЗАГРУЖЕН !";
let point='<option value="'+arans[1]+'"
id="'+arans[1]+'">'+arans[1]+'</option>';
document.getElementById("sele").
insertAdjacentHTML("beforeend", point);
}
if(arans[0]==2)
but1.value="НЕКОРРЕКТНЫЕ ДАННЫЕ !";
setTimeout(()=>{but1.value="Загрузить";}, 2000);
}
document.getElementById("but2").
addEventListener("click", del);
...
let but2=document.getElementById("but2");
function del()
{
if(window.confirm("Вы действительно хотите
удалить этот файл?")==true)
{
let dt=new FormData(document.forms.dat2);
106
let re=new XMLHttpRequest();
re.open("POST", "delfile.php", true);
re.send(dt);
re.addEventListener("load", see);
}
}
...
if(isset($_POST['sele']) && strlen($_POST['sele'])>2)
{
unlink('file/'.$_POST['sele']);
echo '1';
}
else
echo '2';
...
function see()
{
let ans=this.responseText;
if(ans==1)
{
but2.value="ФАЙЛ УДАЛЕН !";
let el=document.getElementById("sele").value;
document.getElementById(el).remove();
}
if(ans==2)
but2.value="НЕКОРРЕКТНЫЕ ДЕЙСТВИЯ !";
setTimeout(()=>{but2.value="Удалить";}, 2000);
}
let el=document.getElementById("sele").value;
document.getElementById(el).remove();
107
13. СПИСОК СТРАНИЦ
Данную страницу мы оставили на десерт, так как с нее начинается до-
вольно большой блок, который мы будем освещать на протяжении четырех
глав. Сама вкладка устроена довольно просто — ей мы посвятим только одну
главу. Но здесь открывается путь к редактору страниц. А он, как вы помните,
является наиболее сложной частью нашей CMS. Описанию редактора мы уде-
лим внимание в трех главах подряд. Собственно, завершив рассмотрение ре-
дактора, мы тем самым подведем черту под изучением системы управления.
Но пока вернемся к заявленной теме — странице со списком. В ее работе
участвуют следующие файлы:
— page.php — формирует раздел создания и удаления страниц сайта;
— css/page.css — определяет дизайн раздела;
— js/page.js — формирует запросы на создание и удаление страниц;
— newpage.php — программа создания новых страниц;
— delpage.php — программа удаления лишних страниц;
— content/cont.txt и content/index.txt — текстовые файлы с данными
страницы «Контакты» и главной страницы.
Рис. 13.1.1
Список существующих страниц и форма добавления новых
108
Сразу после удаления лишнего документа он исчезает из списка. Сразу по-
сле добавления нового документа он появляется в списке на последнем месте.
В следующем разделе мы приступим к подробному рассмотрению модулей.
109
Заполняются ячейки таблицы следующим образом. По аналогии с файлом
index.php создаем ассоциативный массив, открываем директорию content, в
цикле считываем имена текстовых файлов и по очереди загружаем их содержи-
мое в переменную:
$srtar=array();
$opdir=opendir('content');
while($redir=readdir($opdir))
{
if(strpos($redir, '.'))
{
$rep=str_replace('.txt', '', $redir);
$name=file('content/'.$redir);
...
}
}
closedir($opdir);
$pict=' ';
...
$srtar[$name[0]].=$pict.'</td></tr>';
if($rep!='index')
$pict='<input type="hidden" id="pas" name="pas"
value="'.$pas.'">
110
<input type="hidden" name="delp" value="'.$rep.'">
<img src="draw/basket.png" class="imdel"
id="del'.$rep.'" alt="..." title="...">';
$srtar[$name[0]].=$pict.'</td></tr>';
$newar=ksort($srtar);
foreach ($srtar as $key=>$value)
echo $srtar[$key];
echo '</table>
...
let idc=ev.target.id;
let pg=idc.split("del");
if(isset($_POST['delp']))
{
unlink('content/'.$_POST['delp'].'.txt');
echo '1;'.$_POST['delp'];
}
function see()
{
let ans=this.responseText;
let arans=ans.split(";");
if(arans[0]==1)
{
let el=arans[1]+"22";
document.getElementById(el).remove();
}
}
Процесс завершен.
13.4. Блок добавления новых страниц
Этот модуль довольно элементарный — он представляет собой обычную
форму, в которой необходимо заполнить все поля:
<form method="POST" name="dat">
<table id="newpage">
<caption id="capnewp">Создать новую страницу</caption>
<tr>
<td class="rig td">Название</td>
<td class="td"><input id="name" name="name"
minlength="2" maxlength="30"></td>
</tr>
<tr>
<td class="rig td">Идентификатор</td>
<td class="td"><input id="ident" name="ident"
minlength="3" maxlength="10"></td>
</tr>
<tr>
<td class="rig td">Рейтинг</td>
112
<td class="td"><input id="namber" name="namber"
minlength="1" maxlength="2"></td>
</tr>
<tr>
<td class="rig td">Видимость</td>
<td class="td"><select name="sele">
<option selected value="НЕТ">НЕТ</option>
<option value="ДА">ДА</option>
</select></td>
</tr>
</table>
let but=document.getElementById("but");
113
|| document.getElementById("name").value.length>30)
{
but.value="НЕВЕРНАЯ ДЛИНА НАЗВАНИЯ СТРАНИЦЫ !";
return false;
}
else
{
if(document.getElementById("ident").value.
length<3 ||
document.getElementById("ident").value.
length>10)
{
but.value="НЕВЕРНАЯ ДЛИНА ИДЕНТИФИКАТОРА !";
return false;
}
else
{
if(document.getElementById("namber").value
.length<1 ||
document.getElementById("namber").
value.length>2)
{
but.value="НЕВЕРНАЯ ДЛИНА РЕЙТИНГА !";
return false;
}
else
{
...
}
}
}
}
file_put_contents
('content/'.$_POST['ident'].'.txt', $con);
...
}
else
114
echo '2';
$con=$_POST['namber']."\n".$_POST['sele']."\n".
$_POST['name'].
function show()
{
let ans=this.responseText;
let arans=ans.split(";");
if(arans[0]==1)
{
let point='...';
document.getElementById("list").
insertAdjacentHTML("beforeend", point);
but.value="СТРАНИЦА СОЗДАНА !";
}
if(arans[0]==2)
but.value="НЕКОРРЕКТНЫЕ ДАННЫЕ !";
setTimeout(()=>{but.value="Создать";}, 2000);
}
115
14. БАЗОВЫЕ КОМПОНЕНТЫ РЕДАКТОРА СТРАНИЦ
Редактор контента, пожалуй, наиболее своеобразный компонент нашей CMS.
Для разработчиков, привыкших к стандартным системам, он выглядит крайне не-
обычно. Во-первых, отсутствует специальное WYSIWYG-окно, в котором выпол-
няются все манипуляции с текстом, рисунками, таблицами и т. д. Во-вторых, окно с
HTML-кодом существует как бы отдельно и открывается по клику на соответству-
ющей кнопке. В-третьих, под панелью редактирования расположился большой
фрейм, в который полностью выводится требуемая страница. Все действия с кон-
тентом происходят в трех ее блоках — основном, рекламном и нижнем — прямо во
фрейме, благодаря чему вы сразу видите, как будет выглядеть страница после тех
или иных изменений. Напомним, что содержание рекламного и нижнего блоков по-
вторяется на всех страницах. Наполнять два последних можно, зайдя в редактор
любой страницы. Наконец, последний (четвертый) пункт — панель редактирования
можно перемещать по фрейму в вертикальном направлении, тем самым располагая
ее в наиболее удобном месте.
Перечислим компоненты редактора:
— edit.php — формирует страницу редактора;
— css/edit.css — отвечает за внешний вид редактора и его отдельных
элементов;
— js/edit.js — выполняет основной объем работы по всем манипуляциям,
которые предусмотрены в редакторе;
— rec.php — записывает результаты в текстовые файлы страниц, рекла-
мы и нижнего блока;
— content/cont.txt и content/index.txt — текстовые файлы с данными
страницы «Контакты» и главной страницы;
— set/advert.txt — файл хранения рекламной информации;
— set/footer.txt — файл хранения контента нижнего блока.
$test_adr=$_POST["edit"];
Рис. 14.1.1
Внешний вид редактора
Создаем переменную-идентификатор, по значению которой будем су-
дить, запрошена существующая страница или нет:
$ch=0;
117
Если совпадение найдено, вводим новую переменную $adr, которой при-
сваиваем значение временной переменной:
$adr=$test_adr;
$ch=1;
break;
closedir($opdir);
if($ch==0)
{
echo '...
<form method="POST" action="cms.php">
<p id="passw"><input type="password"
name="pas" minlength="5" maxlength="10"
id="pas"></p>
</form>
</body>
</html> ';
return;
}
<div id="bpan">
...
</div>
Как уже было сказано, все эти элементы перемещаются вверх-вниз, со-
храняя взаимное расположение. За счет чего достигается данный эффект, мы
выясним в главе 15.
118
чения режимов его видимости есть специальная вкладка (или кнопка — кому
как удобнее называть) с надписью «ОТКРЫТЬ HTML-КОД»:
Рис. 14.2.1
Окно HTML-редактора
В визуальном режиме выбор редактируемого блока происходит на глав-
ной панели из выпадающего списка «Редактировать» после нажатия кнопки
«Выбрать». Предположим, мы выбрали пункт «Основное содержание» и нажа-
ли кнопку. На 2 секунды она станет голубой, подтверждая, что выбор сделан, а
затем примет исходный вид. Теперь можно вставить курсор в выбранную об-
ласть и начать формирование или изменение основного контента. Выберем ре-
жим «Блок рекламы» и снова нажмем кнопку «Выбрать». Теперь можно вста-
вить курсор в правый блок и поменять его текст, рисунок или что-то добавить к
имеющемуся контенту.
Все изменения, которые произошли с контентом в визуальном режиме,
передаются в HTML-окно в момент нажатия вкладки «ОТКРЫТЬ HTML-КОД».
119
В обратном направлении — в страницу, загруженную во фрейм, — передача
кода выполняется при скрытии текстового поля. Кнопка «Записать» активна
только в визуальном режиме. Но при этом все данные для записи берутся из
текстового окна. Такой способ выбран, чтобы вся информация концентрирова-
лась в одном месте в одном контейнере.
Контейнер form необходим для передачи данных серверной программе
записи rec.php.
В форме 9 полей — текстовое с HTML-кодом основного содержания:
и 8 скрытых:
— с именем файла, предназначенного для перезаписи (если записываются
данные из блока основного содержания);
— с паролем;
Рис. 14.3.1
Главная панель
Чтобы вывести список, напишем вот такой код:
Редактировать:
<select id="sel">
<option selected value="1">Основное содержание</option>
<option value="2">Блок рекламы</option>
<option value="3">Нижний блок</option>
</select>
<input type="button" value="Выбрать" id="selrec">
121
Кнопки включения/отключения режима перемещения панели находятся у
ее правого края:
В качестве основы для главной панели служат слой div и таблица с жест-
ко заданными размерами:
<div id="panel">
<table id="pan">
<tr>
<td id="td1">Редактировать:
<!-- Список блоков -->
...
<!-- Кнопка выбора -->
...</td>
<td id="td2">
<!-- Кнопка записи -->
...</td>
</tr>
<tr>
Хотя кнопки при наведении указателя мыши дают подсказки, для чего
они предназначены, на всякий случай перечислим их функции. Будем считать
кнопки слева направо.
1. Настройка основных параметров страницы. Нажмите эту кнопку,
чтобы открыть окно, в котором можно ввести рейтинг страницы, ее заголовок,
установить видимость, добавить описание и ключевые слова.
2. Копирование фрагмента. Копирует только текстовое содержимое.
Если необходимо скопировать фрагмент вместе с форматированием и элемен-
тами, выделите его, нажмите правую кнопку мыши и в контекстном списке вы-
берите пункт «Копировать».
122
3. Удаление форматирования. Удаляет все HTML-теги из выделенного
фрагмента.
4. Вставка линии. При нажатии этой кнопки открывается вкладка с
настройками линии. Закрывается либо при нажатии на пиктограмму в виде кре-
стика, либо при вставке линии в окно редактирования. Правило распространя-
ется на все остальные вкладки, поэтому в дальнейшем автор не станет напоми-
нать о нем.
5. Вставка таблицы. Открывает вкладку с настройками таблицы.
6. Вставка рисунка. Открывает панель выбора и настроек рисунка.
7. Вставка фрейма. Открывает окно с настройками фрейма.
8. Выбор символа. Выводит на экран список из 50 символов, которые
можно вставить в текст.
9. Маркированный список. Необходимо сделать выделение и нажать
данную кнопку, чтобы превратить текст в маркированный список.
10. Добавить ссылку. Открывает окно настроек ссылки.
11. Удалить ссылку. Удаляет выделенную ссылку, оставляя только ее
текст.
12. Добавить заголовок. Открывает вкладку с настройками заголовков.
13. Выравнивание текста. Выводит панель с настройками вырав-
нивания.
14. Выбор шрифта. Открывает окно с настройками шрифта.
15. Выделение жирным. Необходимо выделить текст и нажать кнопку.
У следующих пяти кнопок принцип действия аналогичен. Делается выделение
в тексте и нажимается кнопка.
16. Выделение курсивом.
17. Выделение подчеркиванием.
18. Выделение зачеркиванием.
19. Сделать фрагмент текста надстрочным.
20. Сделать фрагмент текста подстрочным.
21. Сделать текст цветным. Сначала необходимо открыть окно настро-
ек цвета, выбрать интересующий оттенок, выделить фрагмент и нажать данную
кнопку.
22. Открыть окно выбора цвета. Открывает вкладку с палитрой цве-
тов (рис. 14.3.2). Напоминаем, что у браузера Firefox палитра цветов отличается
внешним видом. Об этом мы говорили в главе 10.
23. Сделать фон текста цветным. Сначала необходимо открыть окно
настроек цвета, выбрать интересующий оттенок, выделить фрагмент и нажать
данную кнопку.
123
Рис. 14.3.2
Окно выбора цвета в большинстве браузеров
Рис. 14.4.1
Основные настройки главной страницы и остальных страниц
Запись основных настроек происходит только тогда, когда в списке «Ре-
дактировать» выбрано основное содержание. Если нажать кнопку записи в ре-
124
жиме редактирования рекламы или нижнего блока, запись основных настроек
для данной страницы не будет выполнена — они останутся прежними.
Вкладки основных настроек создаются следующим кодом.
Считываем из папки content содержимое того txt-файла, который служит
основой, загруженной в редактор страницы:
$meta=file('content/'.$adr.'.txt');
if($adr=='index')
{
...
}
else
{
echo '<input id="meta1" class="inptx"
value="'; echo rtrim($meta[0]); echo '">
Показывать: <select id="meta2"
class="sele">';
if(rtrim($meta[1])=='ДА')
echo '<option selected value="ДА">ДА</option>
<option value="НЕТ">НЕТ</option>
</select>';
else
echo '<option selected value="НЕТ">НЕТ</option>
<option value="ДА">ДА</option>
</select>';
}
125
Остальные три поля при загрузке любой страницы содержат соответ-
ствующие данные из текстового файла:
Рис. 14.5.1
Кнопки простого редактирования
Перечень кнопок простого редактирования:
— копирование фрагмента;
— удаление форматирования;
— маркированный список;
— удаление ссылки;
— выделение жирным;
— выделение курсивом;
— выделение подчеркиванием;
— выделение зачеркиванием;
— сделать фрагмент текста надстрочным;
— сделать фрагмент текста подстрочным.
В разметке код этих кнопок выглядит следующим образом:
126
<img src="draw/format.jpg" id="forma" class="pers"
alt="Очистить формат" title="...">
<img src="draw/ul_li.jpg" id="ulli" class="pers"
alt="Создать маркированный список" title="...">
<img src="draw/del_link.jpg" id="delin" class="pers"
alt="Удалить ссылку" title="...">
<img src="draw/bold.jpg" id="bol" class="but"
alt="Жирный" title="...">
<img src="draw/ital.jpg" id="ital" class="but"
alt="Курсив" title="...">
<img src="draw/under.jpg" id="under" class="but"
alt="Подчеркнутый" title="...">
<img src="draw/strike.jpg" id="strik" class="but"
alt="Зачеркнутый" title="...">
<img src="draw/sup.jpg" id="sup" class="but"
alt="Надстрочный" title="...">
<img src="draw/sub.jpg" id="sub" class="but"
alt="Подстрочный" title="...">
Рис. 14.5.2
Предупреждение о том, что текст не выделен
127
вид. Для этого предназначены специальные вкладки, которые появляются на
экране при нажатии соответствующей кнопки.
Первая на очереди — кнопка вставки линии. Вкладка с элементами
настройки линий показана на рисунке 14.6.1. Вы можете выбрать толщину, ши-
рину и цвет. При введении толщины необходимо указать числовое значение и
размерность — пиксели, записанные латинскими буквами в сокращенном виде
(px). Например, так: 3px. Ширина может быть назначена в пикселях или про-
центах. Соответственно в этом поле необходимо указать значения так: 200px
или 50%.
Обратите внимание! Для всех остальных вкладок действует анало-
гичный принцип: вводя числовые параметры, необходимо указывать не
только число, но также единицы измерения, указанные в тексте перед со-
ответствующим полем (без пробелов после числа)!
Завершив выбор настроек, вставьте курсор в то место, куда вы хотите по-
местить линию, и нажмите кнопку «Вставить». Вкладка скроется, а линия по-
явится в редактируемой области. Если вы забыли поместить курсор, то линия
окажется в самой верхней части редактируемого блока. Кстати, это правило со-
блюдается и при добавлении всех остальных самостоятельных элементов: таб-
лицы, рисунка, фрейма и символа.
Можно вставить линию, не вводя никаких значений. В этом случае она
будет черной, толщиной 1 пиксель и шириной 100%.
Рис. 14.6.1
Окно настроек линий
Ниже приведен код, создающий данную вкладку на странице редактора:
<div id="hr_d" class="cust">
<img src=" draw/close.png" id="hr_i" class="cldiv"
alt="Закрыть" title="...">
<div class="deploy">
Толщина, px: <input id="hr1" class="inptx">
Ширина, px или %: <input id="hr2" class="inptx">
Цвет: <input type="color" id="hr3c"
class="colored" title="...">
<input type="button" id="buthr" class="butin"
value="Вставить" title="...">
</div>
</div>
128
— количество строк;
— количество столбцов
— внутренний зазор (то есть расстояние от границ ячейки до ее содержи-
мого);
— внешний зазор (то есть расстояние от границ таблицы до соседних
элементов);
— шрифт, его размер и цвет;
— толщину рамки и ее цвет;
— цвет фона таблицы;
— положение в тексте или среди других элементов.
Рис. 14.7.1
Окно настроек таблиц
Программа не даст создать таблицу, если вы не укажете количество строк
или столбцов. Об этом появится предупреждение, которое вы можете видеть на ри-
сунке 14.7.2.
Рис. 14.7.2
Окно предупреждения об отсутствии обязательных параметров при создании таблицы
Если вы укажете в настройках только количество строк и столбцов, то
будет создана таблица с рамкой черного цвета толщиной 1 пиксель и шириной,
которая зависит от содержимого ячеек.
129
<br>
Внешний зазор, px: <input id="tab5" class="inptx">
Шрифт: <select id="tab6" class="sele">
<option selected value="Tahoma">Tahoma</option>
<option value="Arial">Arial</option>
...
<option value="Times New Roman">
Times New Roman</option>
</select>
Размер, px: <input id="tab7" class="inptx">
Цвет шрифта: <input type="color" id="tab8c"
class="colored" title="...">
<br>
Рамка, px: <input id="tab9" class="inptx">
Цвет рамки: <input type="color" id="tab10c"
class="colored" title="...">
Цвет фона: <input type="color" id="tab11c"
class="colored" value="#FFFFFF" title="...">
Положение: <select id="tab12" class="sele">
<option selected value="no">НЕТ</option>
<option value="left">Слева</option>
<option value="right">Справа</option>
</select>
<input type="button" id="butab" class="butin"
value="Вставить" title="...">
</div>
</div>
Рис. 14.8.1
Окно выбора и настройки изображения
130
Скрипт добавления рисунка требует двух обязательных параметров:
— адрес внешнего фото или имя внутреннего (одно из двух);
— подпись к рисунку (обязательное условие Консорциума Всемирной
паутины — атрибут alt с текстом должен присутствовать в теге img).
Если вы оставите остальные поля незаполненными, то будет вставлена
картинка шириной 250px с рамкой черного цвета толщиной 1px.
Код вкладки выбора изображения:
<div id="img_d" class="cust bighei">
<img src="draw/close.png" id="img_i" class="cldiv"
alt="Закрыть" title="...">
<div class="deploy">
Внешнее фото: <input id="ima1" class="inpbig">
Фото с сервера: <input id="ima2" class="inpmid">
<input type="button" id="list" class="swit butin"
value="Выбрать" title="...">
<br>
Подпись: <input id="ima3" class="inpbig">
Положение: <select id="ima4" class="sele">
<option selected value="no">НЕТ</option>
<option value="left">Слева</option>
<option value="right">Справа</option>
</select>
Внешний зазор, px: <input id="ima5" class="inptx">
<br>
</div>
131
просто закрыть вкладку без выбора рисунка, нажмите пиктограмму «крестик» в
левом верхнем углу.
Рис. 14.8.2
Панель выбора рисунков из папки img нашего проекта
HTML-код окна выбора внутреннего снимка:
<div id="list_d">
<img src="draw/close.png" id="list_i" class="cldiv"
alt="Закрыть" title="Закрыть">
<p id="p_list">';
$opdir=opendir("img");
while($redir=readdir($opdir))
{
if(strpos($redir, "."))
echo '<img class="roster" src="img/'.$redir.'" alt="Фото">';
}
closedir($opdir);
echo '</p>
</div>
$opdir=opendir("img");
while($redir=readdir($opdir))
{
...
}
closedir($opdir);
132
Затем отсекаем лишние символы текущего и вышестоящего каталогов:
if(strpos($redir, "."))
...
Рис. 14.9.1
Окно настройки фреймов
При отсутствии необходимых параметров вставляется фрейм с черной
рамкой толщиной 1 px и размерами в соответствии с внутренними установками
браузера (обычно ширина такого фрейма примерно 300 пикселей).
Обратите внимание: в окне фрейма будет показана страница, загружен-
ная только по протоколу https. Так происходит во всех браузерах — из сообра-
жений безопасности.
Код вкладки с настройками фреймов:
<div id="ifr_d" class="cust bighei">
<img src="draw/close.png" id="ifr_i" class="cldiv"
alt="Закрыть" title="...">
<div class="deploy">
Адрес загружаемой страницы:
<input id="ifr1" class="inpbig">
Ширина, px: <input id="ifr2" class="inptx">
<br>
133
<option value="right">Справа</option>
</select>
Рамка, px: <input id="ifr5" class="inptx">
Цвет рамки: <input type="color" id="ifr6c"
class="colored" title="...">
<br>
Внешний зазор, px: <input id="ifr7" class="inptx">
<input type="button" id="butifr" class="butin"
value="Вставить" title="...">
</div>
</div>
Рис. 14.10.1
Окно выбора символов
Вообще, полезных символов очень много, но автор выбрал лишь
50 наиболее часто применяемых (на его взгляд).
Код вкладки занимает в документе довольно большой объем, поэтому
приведем его в сокращенном виде:
<div id="copyr_sym">
<input type="button" class="sym" id="s1"
value="¥">
...
<input type="button" class="sym" id="s25"
value="←">
<br>
<input type="button" class="sym" id="s26"
value="→">
...
<input type="button" class="sym" id="s50"
value="χ">
</div>
</div>
134
В коде страницы почти все символы записаны в виде HTML-сущностей:
¥, § и т. д. В окне редактирования они преобразуются в реальные
символы.
Рис. 14.11.1
Окно настроек ссылок
Начальные установки вкладки после ее открытия: выбрана внутренняя
страница, цвет ссылки — черный, с подчеркиванием.
Чтобы добавить ссылку, откройте вкладку, выполните требуемые
настройки, выделите текст и нажмите кнопку «Вставить». Забыли сделать вы-
деление? Появится окно с предупреждением.
Код вкладки:
135
<option value="mailto:">mailto:</option>
</select>
<input id="link2" class="inpbig"><br>
Открывать в новом окне: <select id="link3"
class="sele">
<option selected value="yes">ДА</option>
<option value="no">НЕТ</option>
</select>
Ссылка на страницу: <select id="link4"
class="sele">
...
</select>
Ссылка на файл: <select id="link7" class="sele">
<option selected value="999"> </option>
...
</select><br>
Оформление: <select id="link5" class="sele">
<option selected value="yes">
С подчеркиванием</option>
<option value="no">Без подчеркивания</option>
</select>
Цвет: <input type="color" id="link6c"
class="colored" title="...">
<input type="button" id="butlink" class="butin"
value="Вставить" title="...">
</div>
</div>
$ident=0;
136
уже знакомым нам методом отсекаем символы текущего и вышестоящего ката-
логов:
if(strpos($redir, "."))
{
...
}
Поочередно заносим в массив содержимое каждого файла:
$arpage=file('content/'.$redir);
if($ident==0)
{
echo '<option selected value="'.$rep.'">'.
rtrim($arpage[2]).'</option>';
...
}
$ident=1;
Теперь выражение
if($ident==0)
137
В качестве значений пунктов списка мы используем идентификаторы
файлов (вот для чего была нужна переменная $rep), а между открывающим и
закрывающим тегами option вписываем названия страниц (заодно отрезая в
конце символы перевода строк):
rtrim($arpage[2])
echo '</select>
...
138
Откройте вкладку, выполните требуемые настройки, выделите текст, кото-
рый станет заголовком, и нажмите кнопку «Вставить». Вы получите заголовок
выбранного уровня.
Рис. 14.12.1
Вкладка настроек заголовков
HTML-код блока настроек заголовков:
<div id="h16_d" class="cust">
<img src="draw/close.png" id="h16_i" class="cldiv"
alt="Закрыть" title="...">
<div class="deploy">
Заголовок: <select id="h161" class="sele">
<option selected value="h1">h1</option>
<option value="h2">h2</option>
...
<option value="h6">h6</option>
</select>
Шрифт: <select id="h162" class="sele">
<option selected value="Tahoma">Tahoma</option>
<option value="Arial">Arial</option>
...
<option value="Times New Roman">
Times New Roman</option>
</select>
Размер, px: <input id="h163" class="inptx">
Цвет шрифта: <input type="color" id="h164c"
class="colored" title="...">
<br>
<input type="button" id="buth16" class="butin"
value="Вставить" title="...">
</div>
</div>
Рис. 14.13.1
Панель настроек выравнивания текста в абзацах
Код блока настроек выравнивания текста:
<div id="equa_d" class="cust">
<img src="draw/close.png" id="equa_i" class="cldiv"
alt="Закрыть" title="...">
<div class="deploy">
Выравнивание: <select id="equa1" class="sele">
<option selected value="left">По левому краю
</option>
<option value="center">По центру</option>
<option value="right">По правому краю</option>
<option value="justify">По ширине</option>
</select>
Шрифт: <select id="equa2" class="sele">
<option selected value="Tahoma">Tahoma</option>
<option value="Arial">Arial</option>
...
<option value="Times New Roman">
Times New Roman</option>
</select>
Размер, px: <input id="equa3" class="inptx">
<br>
Цвет шрифта:
<input type="color" id="equa4c"
class="colored" title="...">
Отступ начала абзаца, px:
<input id="equa5" class="inptx">
<input type="button" id="butequa" class="butin"
value="Вставить" title="...">
</div>
</div>
140
ходима на случай, если надо выделить одно или несколько слов шрифтом, от-
личающимся от остального текста.
Панель имеет уже хорошо знакомые вам три параметра: шрифт, цвет и
размер в пикселях.
Так как в этом окне нет каких-либо особенностей, на которые необходимо
обратить внимание, просто посмотрим его HTML-код. Он максимально прост:
<div id="font_d" class="cust">
<img src="draw/close.png" id="font_i" class="cldiv"
alt="Закрыть" title="...">
<div class="deploy">
Шрифт: <select id="font1" class="sele">
<option selected value="Tahoma">Tahoma</option>
<option value="Arial">Arial</option>
...
<option value="Times New Roman">
Times New Roman</option>
</select>
Размер, px: <input id="font2" class="inptx">
Цвет шрифта: <input type="color" id="font3c"
class="colored" title="...">
<input type="button" id="butfont" class="butin"
value="Вставить" title="...">
</div>
</div>
Рис. 14.14.1
Блок настроек шрифтов
Рис. 14.15.1
Кнопки настроек цвета текста
142
15. ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
Любой редактор всегда состоит как минимум из трех «ингредиентов»:
файла страницы, таблицы стилей и файла со сценариями, написанными на
JavaScript. По сути, JavaScript — это квинтэссенция, альфа и омега, основа
нашего визуального редактора. Именно сценарии меняют или создают контент
для сайта.
Как вы помните, сценарии нашего редактора собраны в файле js/edit.js.
Для начала перечислим компоненты, которые не отвечают за изменение кон-
тента:
— «главный» обработчик, служащий контейнером для всех остальных
обработчиков и функций;
— инструкции выбора редактируемого блока;
— инструкции, обеспечивающие взаимодействие визуального и текстово-
го редакторов;
— всего одна строка кода для фиксации выделенной области в окне визу-
ального редактора;
— функции открытия и закрытия вкладок с настройками;
— сценарий выбора рисунка с сервера (то есть из папки img);
— блок навигации по истории внесенных изменений с возможностью за-
фиксировать начальный, конечный или любой промежуточный результат;
— блок записи контента отредактированной страницы;
— код, отвечающий за перемещение панели.
Двинемся по порядку.
addEventListener("load", function()
{
Регистрация обработчика 1
143
Регистрация обработчика 2
...
Регистрация обработчика N
});
let ed=frames[0].document.getElementById("content");
let te=document.getElementById("tex");
let arr=[];
144
и вводим две переменные:
— счетчик внесенных изменений
let cna=0;
let vnc=0;
document.getElementById("selrec").
addEventListener("click", function()
{
...
}
145
Представим, что у нас уже был выбран какой-то режим, отличный от ре-
жима «Основное содержание». Теперь выберем пункт «Основное содержание».
Мы получим из выпадающего списка значение 1, а значит, условие, вынесенное
в начало блока, будет истинным и начнется выполнение приведенных ранее ин-
струкций.
Первым делом отменяем режим редактирования в ранее выбранном слое,
установив его атрибуту contenteditable значение false:
ed.setAttribute("contenteditable", false);
ed=frames[0].document.getElementById("content");
cna=0;
vnc=0;
arr=[];
arr[0]=ed.innerHTML;
ed.setAttribute("contenteditable", true);
te.value=ed.innerHTML;
if(sr==2)
{
ed.setAttribute("contenteditable", false);
ed=frames[0].document.getElementById("advert");
...
146
}
if(sr==3)
{
ed.setAttribute("contenteditable", false);
ed=frames[0].document.getElementById("footer");
...
}
147
По прошествии 2 секунд возвращаем кнопке первоначальную надпись и
цвет:
setTimeout(()=>{dse.value="Выбрать";
dse.style.background="#FFFFFF";}, 2000);
или на
ed=frames[0].document.getElementById("footer");
te.value=ed.innerHTML;
let tex=document.getElementById("tex").style;
— на кнопку записи
let rec=document.getElementById("rec");
let cou=1;
148
В анонимной функции
document.getElementById("htm").
addEventListener("click", function()
{
...
})
rec.style.opacity=0.2;
document.getElementById("htm").innerHTML=
"СКРЫТЬ HTML-КОД";
cou=2;
ed.innerHTML=te.value;
149
— вкладка текстового редактора скроется
tex.visibility="hidden";
rec.style.opacity=1;
rec.removeAttribute("disabled");
cou=1;
let sel=frames[0].document.getSelection();
let s=document.querySelectorAll(".swit");
150
А затем в цикле регистрируем список обработчиков нажатия этих кнопок:
let idc=s[i].id;
let nid=idc+"_d";
document.getElementById(idc).
addEventListener("click", ins.bind(null, nid));
function clo(c)
{
document.getElementById(c).style.visibility=
"hidden";
}
151
Она срабатывает после нажатия иконки с крестиком или после нажатия
кнопки «Вставить» на вкладке с настройками, а также после нажатия на любом
из знаков вкладки специальных символов.
В качестве аргумента функция получает id окна, которое необходимо за-
крыть. Следующий код регистрирует функцию clo в качестве обработчика
нажатия иконок с крестиком:
let t=document.querySelectorAll(".cldiv");
for(let i=0; i<t.length; i++)
{
let idc=t[i].id;
let nid=idc.replace("_i", "_d");
document.getElementById(idc).
addEventListener("click", clo.bind(null, nid));
}
document.getElementById("p_list").
addEventListener("click", function(ev)
{
...
});
152
Рис. 15.6.1
Панель выбора рисунков из папки img
Как видите, мы регистрируем не все случаи нажатия на каждый рисунок,
а только одно событие — клик в области
<p id="p_list">
...
</p>
окна выбора.
Дальше узнаем, пришелся ли щелчок на пустое пространство или на
изображение:
if(ev.target.tagName=="IMG")
{
...
}
Если условие верно, выясняем имя файла выбранной картинки. Для этого
берем у объекта события атрибут src и разбиваем полученное из него значение
на две части. В качестве разделителя служит имя папки с фотографиями img/:
let pho=ev.target.src.split('img/');
и закрываем вкладку:
document.getElementById("list_d").style.visibility=
"hidden";
153
15.7. Навигация по внесенным изменениям
Редактор спроектирован таким образом, что записывает в память проме-
жуточные результаты изменений, внесенных в контент. Графические кнопки
«Вперед» и «Назад» позволяют перемещаться по этим этапам в прямом и об-
ратном направлении так же, как это делается, например, в программе Word.
Допустим, вы вставили в один из слоев рисунок, а потом выделили одно из
слов цветом, отличным от цвета остального текста. Если теперь один раз
нажать кнопку «Назад», то исчезнет цветовое выделение. Нажимаем второй
раз — исчезает картинка и редактируемый контент приобретает первоначаль-
ный вид. Теперь нажмем кнопку «Вперед» — картинка вновь займет свое ме-
сто. Нажмем кнопку еще раз — вновь появится цветовое выделение слова.
То есть контент примет тот же вид, что был достигнут по завершении послед-
него шага редактирования. Думаю, из этого описания алгоритм навигации по
внесенным изменениям понятен.
Пошаговая запись промежуточных данных выполняется в двух случаях:
— при внесении изменений с помощью кнопок редактирования главной
панели (то есть при изменении форматирования текста или добавлении любых
элементов);
— при нажатии на клавиатуре кнопок со знаками препинания или
«Enter».
Администратор должен учитывать второй случай, так как введенный
текст будет записан в память только после нажатия одной из перечисленных
кнопок.
Сохранение в памяти промежуточных данных выполняет специальная
функция inter. Чтобы обеспечить ее корректную работу, предварительно необ-
ходимо объявить несколько переменных. Сначала создаем пустой массив, в ко-
тором очередной промежуточный результат будет следующим элементом:
let arr=[];
arr[0]=ed.innerHTML;
let cna=0;
let vnc=0;
arr[cna]=ed.innerHTML;
155
Первым делом надо убедиться, что значение идентификатора vnc больше
нуля (то есть результаты изменений не перемотаны до исходного состояния):
if(vnc>0)
{
...
}
vnc--;
ed.innerHTML=arr[vnc];
document.getElementById("forw").addEventListener("click", func-
tion()
{
if(vnc<arr.length-1)
{
vnc++;
ed.innerHTML=arr[vnc];
}
});
if(vnc<arr.length-1)
{
...
}
vnc++;
ed.innerHTML=arr[vnc];
156
15.8. Запись отредактированной страницы
Отправка данных серверной программе для записи в файл и получение
ответа происходят в фоновом режиме. Для этого мы используем технологию
Ajax.
Схема процесса выглядит следующим образом. После нажатия кнопки
«Записать» HTML-код из области визуального представления считывается в
текстовый редактор, который является элементом формы. Вторым элементом
служит скрытое поле, содержащее адрес записываемой страницы. Третье поле
содержит пароль. Четвертое — индекс редактируемой области. И еще пять —
данные основных настроек страницы.
Информация из формы пересылается методом POST скрипту rec.php.
Скрипт проверяет входные параметры и, если они корректные, производит за-
пись в файл. В случае успешной записи rec.php возвращает 1, при неудаче — 2.
Сообщения о результатах на 2 секунды появляются на кнопке отправки данных
(рис. 15.8.1), после чего ей возвращается исходный текст.
Рис. 15.8.1
Сообщение о результатах записи на кнопке отправки данных
Для реализации перечисленных этапов у нас существуют две функции.
Первая запускается после щелчка на кнопке «Записать»:
document.getElementById("rec").
addEventListener("click", function()
{
...
});
document.getElementById("m1s").value=
document.getElementById("meta1").value;
157
document.getElementById("m2s").value=
document.getElementById("meta2").value;
document.getElementById("m3s").value=
document.getElementById("meta3").value;
document.getElementById("m4s").value=
document.getElementById("meta4").value;
document.getElementById("m5s").value=
document.getElementById("meta5").value;
Далее создаем:
— новый объект с данными из формы
let dt=new FormData(document.forms.dat);
re.addEventListener("load", show);
setTimeout(()=>{document.getElementById("rec").
value="Записать";}, 2000);
}
158
Последняя инструкция сообщает программе, что через 2 секунды необхо-
димо вернуть кнопке исходную надпись:
setTimeout(()=>{document.getElementById("rec").
value="Записать";}, 2000);
$str=$_POST['str'];
159
if($ch==0)
{
echo '2';
return;
}
$tex=' ';
if(isset($_POST['tex']))
{
if($_POST['tex']!='')
$tex=$_POST['tex'];
}
else
{
echo '2';
return;
}
$tex=' ';
if(isset($_POST['tex']))
$tex=$_POST['tex'];
$namb=$_POST['namb'];
$meta1=$_POST['m1s'];
$meta2=$_POST['m2s'];
$meta3=$_POST['m3s'];
$meta4=$_POST['m4s'];
$meta5=$_POST['m5s'];
if($namb==2)
{
$fin=$tex;
$adr='set/advert.txt';
}
if($namb==3)
{
$fin=$tex;
$adr='set/footer.txt';
}
if(file_put_contents($adr, $fin))
echo '1';
else
echo '2';
162
Рис. 15.9.1
Перемещение главной панели
Теперь панель можно перемещать. Нажатие кнопки «Стоп» приводит к
удалению упомянутого обработчика:
document.getElementById("bpan").
removeEventListener("mousedown", coor);
163
Первая операция — определение вертикальной координаты указателя:
let v=ev.pageY;
let sv=document.getElementById("bpan").offsetTop;
dv=v-sv;
Рис. 15.9.2
Вычисление начального смещения панели относительно верхней границы окна браузера
и регистрируем обработчик для события перемещения мыши по странице:
addEventListener("mousemove", neco);
function neco(ev)
{
...
}
let nv=ev.pageY;
let fv=nv-dv;
165
16. РЕДАКТОР КОНТЕНТА
В этой главе мы рассмотрим самые главные функции — те, которые поз-
воляют создавать и редактировать контент. Вы узнаете, как:
— записываются основные данные страницы;
— происходит включение режима редактирования;
— выполняется копирование текста;
— удаляются форматирование и ссылки;
— выполняется простое редактирование текста;
— меняется цвет букв или фона текста;
— добавляется разметка маркированного списка;
— вставляются линии, фреймы, рисунки, таблицы, символы;
— создаются ссылки;
— формируются заголовки;
— выравнивается текст в абзацах;
— текст оформляется разными шрифтами.
Но автор, прежде чем приступить к делу, советует во время чтения дан-
ной главы держать открытым на компьютере файл edit.js. А еще лучше допол-
нительно запустить локальный хостинг и не только в теории, но и на практике
наблюдать результаты работы тех или иных функций, написанных на
JavaScript. Так вы достигнете максимально ясного и объемного восприятия ма-
териала.
166
document.getElementById("meta4").value;
document.getElementById("m5s").value=
document.getElementById("meta5").value;
167
Теперь к делу. Регистрируем анонимную функцию в качестве обработчи-
ка события щелчка на кнопке копирования:
document.getElementById("cop").
addEventListener("click", function()
{
...
});
ed.focus();
if(sel=="")
alert("Вы не выделили текст!");
else
navigator.clipboard.writeText(sel);
Рис. 16.3.1
Если текст не был выделен, появляется диалоговое окно с предупреждением
document.getElementById("forma").
addEventListener("click", nofr);
document.getElementById("delin").
addEventListener("click", nofr);
168
Устанавливаем фокус на поле редактирования:
ed.focus();
let rng=sel.getRangeAt(0);
let cr=document.createTextNode(sel.toString());
sel.deleteFromDocument();
rng.insertNode(cr);
inter();
let mid=
["bol", "ital", "under", "strik", "sup", "sub"];
169
Обратите внимание, что в первом массиве порядковый номер кнопки с
id=«bol» соответствует порядковому номеру создаваемого этой кнопкой эле-
мента b во втором массиве. И так для всех остальных кнопок.
Поскольку кнопок много, для сокращения кода станем регистрировать
обработчики в цикле. Первым делом создадим массив кнопок, ориентируясь на
то, что все они (и только они) принадлежат к классу but:
let m=document.querySelectorAll(".but");
function emb(v)
{
ed.focus();
if(sel=="")
alert("Вы не выделили текст!");
else
{
let rng=sel.getRangeAt(0);
let elm=document.createElement(v);
rng.surroundContents(elm);
inter();
}
}
let elm=document.createElement(v);
rng.surroundContents(elm);
170
Как видите, термин «простое редактирование» использован автором не
случайно. Действительно, такие действия элементарны: выделил текст, нажал
кнопку и получил искомый результат.
function clr(b)
{
...
}
let elm=document.createElement("span");
После его создания устанавливаем стиль тега, где код цвета определяется
значением из поля с идентификатором ccc:
elm.style=b+"color: "+
document.getElementById("ccc").value;
document.getElementById("col").
addEventListener("click", clr.bind(null, ""));
document.getElementById("backgr").
addEventListener("click",
clr.bind(null, "background-"));
171
16.7. Добавление разметки маркированного списка
Важное замечание к этой функции: чтобы создать список, используйте
перевод на следующую строку, а не на следующий абзац (то есть нажимайте
комбинацию клавиш «Shift» + «Enter», а не просто «Enter»).
Регистрируем обработчик:
document.getElementById("ulli").
addEventListener("click", function()
{
...
});
Устанавливаем фокус.
Проверяем выделение. Если оно есть, присваиваем выделенный фрагмент
новой переменной:
let ulli=sel;
let masulli=ulli.toString().split("\n");
let sum="";
for(let i=0; i<masulli.length; i++)
sum+="<li>"+masulli[i]+"</li>";
ed.getElementsByTagName("UL").length
let len="sul"+ed.getElementsByTagName("UL").length;
elm.id=len;
172
Если созданный элемент — первый, то у списка id будет sul0, если эле-
мент второй, то id списка будет sul1 и т. д.
Вставляем тег ul в окно редактирования:
rng.surroundContents(elm);
frames[0].document.getElementById(len).innerHTML=sum;
inter();
document.getElementById("buthr").
addEventListener("click", function()
{
...
});
let hr1_v=document.getElementById("hr1").value;
let hr2_v=document.getElementById("hr2").value;
let hr3_v=document.getElementById("hr3c").value;
173
На случай, если администратор заполнил не все поля, создаем две пустые
переменные:
let hr1="";
let hr2="";
else
hr1="height: 1px; ";
if(hr2_v!="")
hr2="width: "+hr2_v+"; ";
border: 0;
function place(x, y, z, w, q)
{
174
ed.focus();
let rng=sel.getRangeAt(0);
let elm=document.createElement(x);
if(y!="")
elm.src=y;
elm.style=z;
if(w!="")
{
elm.alt=w;
elm.title=w;
}
rng.surroundContents(elm);
inter();
clo(q);
}
175
и запускаем программу закрытия вкладки с настройками:
clo(q);
Получаем данные:
let ifr1_v=document.getElementById("ifr1").value;
...
let ifr7_v=document.getElementById("ifr7").value;
if(ifr3_v!="")
ifr3="height: "+ifr3_v+"; ";
if(ifr4_v!="no")
ifr4="float: "+ifr4_v+"; ";
if(ifr5_v!="")
ifr5="border: "+ifr5_v+" solid "+ifr6_v+";";
else
ifr5="border: 1px solid "+ifr6_v+";";
if(ifr7_v!="")
ifr7=" margin: "+ifr7_v+";";
176
let sifr=ifr2+ifr3+ifr4+ifr5+ifr7;
Когда введен адрес внешнего рисунка, загружен будет он. Если введены
сразу два адреса — внешнего и внутреннего фото, — то приоритет отдается
внешнему. Если выбрана только внутренняя картинка, то в этом случае будет
загружена она:
if(ima1_v!="")
ima=ima1_v;
else
ima="../img/"+ima2_v;
Данные настроек:
let tab1_v=document.getElementById("tab1").value;
...
let tab12_v=document.getElementById("tab12").value;
которые выполняют:
— запись данных в массив промежуточных этапов редактирования;
— закрытие вкладки с настройками таблицы.
179
16.12. Вставка символов
Символов очень много — 50 штук. Регистрировать для каждого из них
обработчик отдельной строкой — хлопотное и нерациональное занятие. Поэто-
му все события нажатия кнопок символов будем регистрировать в цикле.
Создадим массив кнопок, ориентируясь на то, что все они (и только они)
принадлежат к классу sym:
let q=document.querySelectorAll(".sym");
получаем ее символ:
let smb=q[i].value;
180
addEventListener("click", function()
{
...
});
выполняется проверка выделения с типичным предупреждением в случае его
отсутствия:
if(sel=="")
alert("Вы не выделили текст!");
и завершаем процесс:
181
inter();
clo("link_d");
Хочу также обратить ваше внимание, что при создании ссылок действует
правило, уже знакомое вам по модулю выбора фотографий: когда введены ад-
реса внешней и внутренней ссылок, преимущество имеет внешний адрес.
if(sel=="")
alert("Вы не выделили текст!");
else
{
let rng=sel.getRangeAt(0);
let elm=document.createElement(r);
elm.style=u;
rng.surroundContents(elm);
inter();
clo(j);
}
}
if(h163_v!="")
182
h163=" font-size: "+h163_v+";";
document.getElementById("butequa").
addEventListener("click", function()
{
...
});
let equa1_v=document.getElementById("equa1").value;
...
let equa5_v=document.getElementById("equa5").value;
let equa3="";
let equa5="";
if(equa3_v!="")
equa3=" font-size: "+equa3_v+";";
if(equa5_v!="")
equa5=" text-indent: "+equa5_v+";";
let equares='text-align: '+equa1_v+
'; font-family: '+equa2_v+';'+
equa3+' color: '+equa4_v+';'+equa5;
if(font2_v!="")
font2=" font-size: "+font2_v+";";
let fontres='font-family: '+font1_v+';'+font2+
' color: '+font3_v+';';
wrap("span", fontres, "font_d");
});
184
17. ЗАКЛЮЧЕНИЕ
Мы закончили описание системы управления и разбор ее функций. По сути,
данная книга получилась в некотором роде документацией по изученному про-
граммному обеспечению. Но, конечно, история с CMS на этом не заканчивается.
Ведь это был только первый шаг.
Что же дальше? Варианты профессионального роста могут быть самыми
разными.
Можно, взяв за основу изученный материал, нарастить его функциональ-
ность, увеличить количество настраиваемых параметров и создаваемых страниц.
Можно перевести систему с хранения информации в текстовых файлах на
ее хранение в базе данных.
Можно значительно усложнить систему шифрования пароля и тем самым
повысить уровень безопасности CMS.
Можно, используя полученный опыт, вообще написать что-то новое, не-
обычное и нестандартное.
Путей дальнейшего развития много.
Но в любом случае автор желает вам удачи.
185
ОГЛАВЛЕНИЕ
1. Введение ................................................................................................ 3
1.1. О чем эта книга ................................................................................ 3
1.2. Особенности проекта ...................................................................... 4
1.3. Оформление сценариев ................................................................... 5
2. Прежде чем начать ............................................................................. 7
2.1. CMS .................................................................................................. 7
2.2. WYSIWYG ....................................................................................... 8
2.3. Атрибут contentEditable .................................................................. 8
2.4. Свойство designMode ...................................................................... 9
2.5. Метод getSelection ......................................................................... 10
2.6. Методы createElement и surroundContents ................................... 10
3. Среда разработки .............................................................................. 11
3.1. Выясняем разрядность ОС ........................................................... 12
3.2. Установка пакета Visual C++ ....................................................... 13
3.3. Установка сервера Apache 2.4 ...................................................... 15
3.4. Установка PHP 8............................................................................ 21
3.5. Установка редактора Notepad++ 8 ............................................... 24
3.6. Установка файлов zip-архива
на локальный хостинг .......................................................................... 28
3.7. Перенос проекта на
удаленный хостинг ............................................................................... 29
4. Тестирование программ .................................................................. 36
4.1. Тестирование сценариев в браузерах .......................................... 36
4.2. Тестирование сценариев в валидаторах ...................................... 37
4.3. Кодировка файлов ......................................................................... 40
5. Структура проекта ........................................................................... 41
5.1. Комплектующие системы ............................................................. 41
5.2. Сайт ................................................................................................ 42
5.3. CMS ................................................................................................ 42
6. Вход и главная страница CMS ....................................................... 45
6.1. Вход в систему .............................................................................. 45
6.2. Меню системы ............................................................................... 48
186
7. Замена пароля .................................................................................... 51
7.1. Страница замены пароля .............................................................. 51
7.2. Замена пароля ................................................................................ 52
8. Специальные настройки ................................................................. 57
8.1. Страница специальных настроек ................................................. 57
8.2. Добавление фото ........................................................................... 61
8.3. Просмотр фото............................................................................... 63
8.4. Удаление фото ............................................................................... 65
8.5. Запись e-mail администратора ..................................................... 66
9. Сайт ..................................................................................................... 69
9.1. Варианты компоновки страниц.................................................... 69
9.2. Файл index.php ............................................................................... 71
9.3. Таблица стилей .............................................................................. 77
9.4. Просмотр фото............................................................................... 80
9.5. Страница «Контакты» ................................................................... 83
9.6. Отправка сообщений..................................................................... 86
10. Конструктор сайта .......................................................................... 90
10.1. Страница конструктора .............................................................. 90
10.2. Блоки ............................................................................................ 91
10.3. Вкладки ........................................................................................ 93
10.4. Запись результата ........................................................................ 96
11. Добавление фото.............................................................................. 98
11.1. Страница добавления фото......................................................... 98
11.2. Добавление фото ......................................................................... 99
11.3. Просмотр фото........................................................................... 101
11.4. Удаление фото ........................................................................... 101
12. Добавление файлов ....................................................................... 103
12.1. Страница добавления файлов................................................... 103
12.2. Добавление файла ..................................................................... 105
12.3. Удаление файла ......................................................................... 106
13. Список страниц ............................................................................. 108
13.1. Страница со списком ................................................................ 108
13.2. Блок списка страниц ................................................................. 109
13.3. Удаление лишних страниц ....................................................... 111
13.4. Блок добавления новых страниц .............................................. 112
13.5. Добавление новой страницы .................................................... 113
187
14. Базовые компоненты редактора страниц ................................ 116
14.1. Компоновка редактора .............................................................. 116
14.2. WYSIWYG и текстовый режимы ............................................ 118
14.3. Главная панель .......................................................................... 120
14.4. Основные настройки страницы................................................ 124
14.5. Кнопки простого редактирования ........................................... 126
14.6. Блок настроек линий ................................................................. 127
14.7. Блок настроек таблиц ................................................................ 128
14.8. Блок настроек рисунков............................................................ 130
14.9. Блок настроек фреймов............................................................. 133
14.10. Блок выбора символов ............................................................ 134
14.11. Блок настроек ссылок ............................................................. 135
14.12. Блок настроек заголовков ....................................................... 138
14.13. Блок настроек выравнивания
текста в абзацах .................................................................................. 139
14.14. Блок настроек шрифтов .......................................................... 140
14.15. Блок настроек цвета текста .................................................... 141
14.16. Удаление форматирования и ссылок ..................................... 142
15. Вспомогательные функции ......................................................... 143
15.1. Регистрация «главного» обработчика ..................................... 143
15.2. Выбор редактируемого блока .................................................. 144
15.3. Взаимодействие текстового поля
и редактируемой области .................................................................. 148
15.4. Фиксация в памяти
выделенного фрагмента ..................................................................... 150
15.5. Открытие и закрытие
вкладок с настройками....................................................................... 150
15.6. Выбор рисунка ........................................................................... 152
15.7. Навигация по внесенным изменениям .................................... 154
15.8. Запись отредактированной страницы ...................................... 157
15.9. Перемещение панели ................................................................ 162
16. Редактор контента ........................................................................ 166
16.1. Основные данные страницы ..................................................... 166
16.2. Включение режима редактирования ....................................... 167
16.3. Копирование текста .................................................................. 167
16.4. Удаление форматирования и ссылок ....................................... 168
16.5. Простое редактирование текста ............................................... 169
16.6. Изменение цвета букв или фона текста................................... 171
188
16.7. Добавление разметки
маркированного списка ..................................................................... 172
16.8. Вставка линии ............................................................................ 173
16.9. Вставка фрейма ......................................................................... 176
16.10. Вставка рисунка....................................................................... 177
16.11. Вставка таблицы ...................................................................... 178
16.12. Вставка символов .................................................................... 180
16.13. Добавление ссылки ................................................................. 180
16.14. Добавление заголовка ............................................................. 182
16.15. Выравнивание абзаца .............................................................. 183
16.16. Настройка шрифта .................................................................. 183
17. Заключение .................................................................................... 185
189
Валерий Викторович ЯНЦЕВ
JAVASCRIPT И PHP. CONTENT MANAGEMENT SYSTEM
Учебное пособие