AdminHelper – assistant application for site administrator  Visit site

  • PUG
  • SCSS
  • JavaScript
  • PHP

An application that automates the process of creating new material for the site. With its help, the administrator receives the finished HTML code of the article in a short period of time.

Javascript assistant application for site administrator

The application generates a ready-made HTML code for the article from the materials of the task (images and a Word file), and also saves cropped images to the /images/ folder.

This service, developed for process automation of creating a new page code, helps the site administrator quickly compose an article that includes text, photo and video carousels, link buttons, review sliders and price tables. Then the administrator can paste this code into the admin panel of the site during the creation of a new material.

Application functions are implemented on a bunch of JavaScript + Php. It is possible to create articles for 3 different sites. Layout was carried out using Crystalball (It is a web app project scaffolding tool powered with GULP for frontend development. Out-of-the box it has: PUG templating, SASS styling, WEBPACK bundler).

JavaScript application

Implemented in the application (What does the app do)

  • The simplest authorization in PHP (login.php).
  • Reading Word file (getWordText.php) and inserting formatted text into Ckeditor 4 Html editor
  • Formation of code for link buttons, Price buttons (Page elements tab).
  • For the «Read more» block: getting the Html code of different web pages (getWebPageHtml.php), finding the title image and generating the finished code for this block (Page elements tab).
  • Getting YouTube video titles using PHP (getYoutubeData.php), generating YouTube gallery code (Page elements tab).
  • Formation of code for photo carousels (Page elements tab).
  • Cropping, renaming and saving images to the /images/ directory in PHP (createImageGallery.php).
  • Inserting code from different fields into the resulting field, adding Meta-title and Meta-description to the end of the finished code for 2 types of pages (Service and Blog Article), Copy code button (Ready HTML code tab).
  • Formation of ready-made Html code of price tables from text logically marked up with certain symbols (Price page).
  • The service includes updating price lists through integration with Google Sheets and Google Apps Script. This integration is described here in...

Algorithm of the administrator's work (Demo of the process)

The main stages of work on creating new material for the site

  1. Reception task materials and uploading them to the site folder /adminhelper/files/.
  2. Working in the AdminHelper application.
  3. Inserting the finished HTML code into the Admin panel of the site.

Detailed algorithm of actions

  1. In the mail, open a letter with a task, download the materials (Word file and images) to the computer in the site folder, copy the links for the buttons in the letter.
  2. Upload the downloaded materials to the site in the directory /adminhelper/files/.
  3. Login to AdminHelper App.
  4. Click on the button Get word text, edit the text of the article, if necessary («Editor» tab).
  5. Paste the links copied in the task into the field in the «Page elements» tab. Generate code.
  6. In the «Page elements» tab, in the input field, enter a name for the images. If necessary, in the textarea Photo gallery of results, enter a list of image file names and the last line - a phrase after which you will need to insert a photo carousel.
  7. Click the Generate code button.
  8. Click the Insert All Into Article button.
  9. In the «Ready HTML code» tab, select the type of material (Service or Article) and click on the Copy code button.
  10. Go to the site's admin panel. Add a new material in the required section and paste the previously copied code into the Contents field. Complete the process of creating material on the site.
  11. Ready! Open the created page on the site with text, photo carousels, buttons and a review slider.

The principle of generating HTML code

When generating fragments of HTML code, a markup language is used.

  1. Text is inserted into the textarea field in combination with logical markup as a set of certain characters.
  2. The Generate code button is pressed.
  3. JavaScript handles the click on a specific button by returning a line of code.
  4. Ready HTML code is inserted into the textarea field below.

All fragments according to a certain order are collected into a single resulting code after clicking on the Insert all into article button. The user will be redirected to the Ready HTML Code tab.

Example: link-buttons at the top of an article

To form link-buttons, you need to insert into the textarea:
				          btns
Гнатологическое лечение https://damasclinic.ru/uslugi-i-ceny/stomatologiya/gnatologiya/
Лечение брекетами  https://damasclinic.ru/uslugi-i-ceny/stomatologiya/lechenie-breketami/
Фото результатов стоматологического лечения https://damasclinic.ru/foto-do-i-posle/stomatologija/
				        
The finished code will appear in the box below:
				          <! --- Btns -- >
<ul class="pod-cat">
  <li><a href=")">Гнатологическое лечение (ссылку на ноовую страницу из предыдущего задания</a></li>
  <li><a href="/uslugi-i-ceny/stomatologiya/lechenie-breketami/">Лечение брекетами</a></li>
  <li><a href="/foto-do-i-posle/stomatologija/">Фото результатов стоматологического лечения</a></li>
</ul>
				        

Example: price table for the Pricing section

The Price page in the AdminHelper application.

Table copied from the assignment email (Get Raw Code tab):
				          Коррекция носогубных складок и морщин «марионеток»
Действует акция!
Препарат Juviderm 4 (1 мл)	20 000 руб  14 999 руб
Препарат Juviderm 4 (1 мл) (процедуру проводит доктор Амжад Аль-Юсеф)	25 000 руб
Препарат Juviderm Volift с лидокаином (анестезирующий) (1 мл)	21 000 руб  15 999 руб
Препарат Perfecta (1 мл)	19 000 руб  13 999 руб
Препарат Restyline (1 мл)	13 500 руб
				        
Intermediate text marked up with specific characters (after clicking the «Get Raw Code» button):
				          Коррекция носогубных складок и морщин «марионеток» |
Действует акция! &
Препарат Juviderm 4 (1 мл)  |  20 000 руб $  14 999 руб |
Препарат Juviderm 4 (1 мл) (процедуру проводит доктор Амжад Аль-Юсеф)  |  25 000 руб |
Препарат Juviderm Volift с лидокаином (анестезирующий) (1 мл)  |  21 000 руб $  15 999 руб |
Препарат Perfecta (1 мл)  |  19 000 руб $  13 999 руб |
Препарат Restyline (1 мл)  |  13 500 руб
				        
Ready HTML code (after clicking on the «Generate code» button):
				          <table class="beautiful_table readmore">
<tbody>
  <tr><th colspan="2">
    Коррекция носогубных складок и морщин «марионеток»
    <br/><span style="color: #ff9900;">Действует акция!</span>
  </th></tr>
  <tr><td>Препарат Juviderm 4 (1 мл)</td><td><span style="text-decoration: line-through;">20 000 руб</span> <span style="color: #ff9900;">14 999 руб</span></td></tr>
  <tr><td>Препарат Juviderm 4 (1 мл) (процедуру проводит доктор Амжад Аль-Юсеф)</td><td>25 000 руб</td></tr>
  <tr class="readmore_hide"><td>Препарат Juviderm Volift с лидокаином (анестезирующий) (1 мл)</td><td><span style="text-decoration: line-through;">21 000 руб</span> <span style="color: #ff9900;">15 999 руб</span></td></tr>
  <tr class="readmore_hide"><td>Препарат Perfecta (1 мл)</td><td><span style="text-decoration: line-through;">19 000 руб</span> <span style="color: #ff9900;">13 999 руб</span></td></tr>
  <tr class="readmore_hide"><td>Препарат Restyline (1 мл)</td><td>13 500 руб</td></tr>
  </tbody>
</table>
<div class="show_readmore">Развернуть</div>
<p>&nbsp;</p>
				        

How AdminHelper App helps

AdminHelper performs many operations automatically, thereby significantly reducing the time required to create a new page of the site.

The administrator does not have to:

  • Text: open text in Word; format text by adding H2 headings; copy this text and paste it into the admin panel editor for further work with it.
  • Images: crop them in some graphics editor; create smaller thumbnails; rename images; waste time uploading them to the site.
  • Photo sliders (owl-carousel): manually generate HTML code using image titles (alt) and new filenames (src); insert each carousel in the text after a specific phrase.
  • YouTube carousel: go to YouTube and copy the title of each video; manually generate the HTML code of the gallery.
  • Buttons: manually generate HTML code from links.
  • Price lists: manually generate HTML code for tables for the pages of the Prices section of the site.

Used tools

  • Login
  • Get Word text
  • Page elements
  • Ready-made HTML code
  • Application work
Login Javascript App
Javascript admin panel
Admin panel tabs
Admin helper

Here below is just index.pug and app.js files:

index.pug
					          extends layout/damasclinic

block title
	title Admin Helper App | Damasclinic

block content
	.smarttabs
		span.priority ❶
		input#getWordText._small._infolight(type='button' value='Получить Word текст' onclick="showsnackbar('docx')")
		span._inline-block(style='margin-left:20px;')
			span.priority ❷
			a.b-nav-tab.active(href='#' data-tab='tabeditor' title='Редактирование текста')
				| Редактор
		span._inline-block
			span.priority ❸
			a.b-nav-tab(href='#' data-tab='tabelem' title='Кнопки, Читайте ещё, YouTube галерея')
				| Page Elements
		span._inline-block
			span.priority ❹
			a#tabcodeLink.b-nav-tab(href='#' data-tab='tabcode' title='Код статьи для Админки')
				| Готовый HTML код
		a.b-nav-tab(href='#' data-tab='tabword' title='Текст из Word файла')
			| Docx text

		.smarttabs__content

			#tabeditor.b-tab.active
				.row
					.col.m7
						textarea(name="editor1")
					.col.m5
						h5 Отзывы
						textarea#reviewText._width100(placeholder="Вставь скопированный текст Отзывов")
						input#getReviewCode.button._success(type='button' value='Получить код')
						p Слайдер отзывов (готовый код):
						textarea#readyReviewCode._width100(placeholder="Будет после нажатия Получить код...")

			#tabelem.b-tab
				.row
					.col.m6
						.card
							h5._width75 Кнопки-ссылки, кнопка Прайс, Read more, YT gallery
							p._low
								span._f-warning btns
								| - Кнопки-ссылки /  
								span._f-warning price
								| - кнопка Прайс /  
								span._f-warning read
								|- Read more /  
								span._f-warning yt
								|- YT gallery
							input#getPageElements.button._success(type='button' value='Сформировать код')
							.tooltip.-tooltip-right.pattern Пример кода
								span.tooltiptext._nightblue
									| btns
									|	<br/>Vaser липосакция тела https://damasclinic.ru/service/liposakciya
									|	<br/>Липосакция живота https://damasclinic.ru/service/liposakciya-zhivota
									|	<br/>Липосакция лица https://damasclinic.ru/service/liposakciya-lica
									|	<br/>Липофмилинг ягодиц https://damasclinic.ru/service/lipofiling-yagodic
									br
									|	<br/>price
									|	<br/>https://damasclinic.ru/price/plasticheskaya-hirurgiya#lipostela
									br
									|	<br/>yt
									|	<br/>https://youtube.com/shorts/Ni-QDsmrfig
									|<br/>>https://youtube.com/shorts/tL6VhgpHTjI
									|	<br/>https://youtube.com/shorts/Y_66MKtEFMA
									|	<br/>В А Ж Н О: для YouTube - в конце, чтобы был ID ролика
							textarea#pageElements._width100(placeholder="Вставить элементы для страницы")
							p Готовый код - Page Elements:
							textarea#readyPageElements._width100(placeholder="Будет после нажатия Сформировать код...")

					.col.m6
						.card
							h5 Images for article
							div Фотогалерея рез-тов -
								span._low список Alt
								span._floatRight
									input#stubImageGallery(type='checkbox')
									|  Интимная пластика
									.tooltip.-tooltip-left.pattern ?
										span.tooltiptext._nightblue
											| Сформируется код галереи с картинками-заглушками для проверки 18 лет
							textarea#namelist._width100(placeholder="Каждое название с новой строки и Фразу в последней строке, после которой будет фотогалерея")
							input#namepic._width50(type='text' placeholder='Имя файла картинки')
							input#getImageGallery.button._success(type='button' value='Сформировать код')
							span.disabled
								input#insertElements._info._disabled(type='button' value='Вставить всё в статью' onclick="showsnackbar('articlecode')")
							//- input#insertReviews._infolight(type='button' value='Вставить Отзывы в конец')
							//- p._low Если были Отзывы, то сначала Сформировать их код (вкладка Редактор), а затем нажать "Вставить Отзывы в конец"
							p Готовый код фото-галерей:
							textarea#imagesCode._width100(placeholder="Будет код после нажатия на Сформировать код...")

			#tabcode.b-tab
				h5 Готовый HTML код
				p._clear Добавить Meta-description
					span._low (в конец статьи)  
					input.add-meta.button(type='button' value='Услуга' data-datatype='service')
					input.add-meta.button(type='button' value='Статья' data-datatype='article')
					span.disabled
						button#copyArticleCode._info._disabled Скопировать код
				textarea#articleCode._width100._height400(placeholder="Готовый код для статьи - вставить в Админку")

			#tabword.b-tab
				h5 Docx to Html
				p
					small PHP class: https://github.com/xylude/Docx-to-HTML
				textarea#wordText._width100._height400
	#docx.snackbar DOCX текст получен!
	#articlecode.snackbar._info Код статьи сформирован!
	#noteNoContent.snackbar._warning Нет содержимого!
	#noteNoFileName.snackbar._warning Введи Имя файла картинки!
	#loginPlease.snackbar._warning Войдите в Admin Helper!
	#articlecopy.snackbar._info Код скопирован!
					        
app.js
										'use strict';

(function() {

  const connectTabs = new Tabs(),
        editors = document.getElementsByName('editor1'),
        urlAddress = window.location.pathname,
        // Login
        loginBtn = document.getElementById('login');

  toggleSidebarMenu();
  highlightActiveMenuItem('.topnav');
  highlightActiveMenuItem('.listnav');
  if (editors[0] !== undefined) ckeditorInit();

  function highlightActiveMenuItem(menu) {
    const menuLinks = document.querySelectorAll(menu + ' li > a');

    menuLinks.forEach(function (link) {
      const linkHref = link.getAttribute('href');
      link.classList.remove('active');

      if ( linkHref.slice(1) === urlAddress.slice(12) && linkHref !== '#' ||
          urlAddress.indexOf('damas') !== -1 && link.classList.contains('damas') ||
          urlAddress.indexOf('dramjad') !== -1 && link.classList.contains('dramjad') ||
          urlAddress.indexOf('make-website') !== -1 && link.classList.contains('makewebsite') ||
          urlAddress.indexOf('damas') === -1 && urlAddress.indexOf('dramjad') === -1 && urlAddress.indexOf('make-website') === -1 && link.classList.contains('damas')
        ) link.classList.add('active');
    });
  }

  function toggleSidebarMenu() {
    const bodyEl = document.querySelector('body'),
          hamburger = document.querySelector('.hamburger');
    hamburger.addEventListener('click', function () {
      bodyEl.classList.toggle('hidden-sidebar');
    });
  }

  function ckeditorInit() {
    const editor1 = CKEDITOR.replace( 'editor1', {
      height: 500,
      extraAllowedContent: 'span(*);p(*);a(*);div(*);table(*);*[align];*[style];*[class];*[data-fancybox]'
    } );

    editor1.on( 'instanceReady', function( evt ) {
      evt.editor.addCommand( 'h2' , new CKEDITOR.styleCommand( new CKEDITOR.style({ element: 'h2' } )) );
      evt.editor.setKeystroke( CKEDITOR.SHIFT + 50 /*2*/, 'h2');
    });
  }

  function Tabs() {
    let bindAll = function() {
      let menuElements = document.querySelectorAll('[data-tab]');
      for(let i = 0; i < menuElements.length ; i++) {
        menuElements[i].addEventListener('click', change, false);
      }
    }

    let clear = function() {
      let menuElements = document.querySelectorAll('[data-tab]');
      for(let i = 0; i < menuElements.length ; i++) {
        menuElements[i].classList.remove('active');
        let id = menuElements[i].getAttribute('data-tab');
        document.getElementById(id).classList.remove('active');
      }
    }

    let change = function(e) {
      clear();
      e.target.classList.add('active');
      let id = e.currentTarget.getAttribute('data-tab');
      document.getElementById(id).classList.add('active');
    }

    bindAll();
  }

}());

									
Back to top