В данной статье я хочу рассказать про мой callback-виджет, который я решил разработать для поставленной задачи!
Суть задачи заключалась в следующем:
Решение:
Перед тем как начать писать код, я продумал архитектуру и из самых простых инструментов для backend я использовал php, а front-end native js + angular без использования другихjquery-подобных библиотек. Для того, чтобы виджет был уникальным, каждый виджет имеет свой универсальный ключ, по которому мы и будем получать все данные по виджету.
Я не хочу писать огромные куски кода логики, которые каждый разработчик в силах додумать, а хотел бы отметить те моменты, на которые я потратил больше всего времени, хотя и в веб-разработке уже не первый год.
Приступим к разбору узких мест!
Как выглядит код для вставки на сайт (index.html):
(key — это сгенерированный md5 ключ, по которому я получаю всю информацию по виджету, а не по ID это очень важно, а рекомендуемое место вставки это до закрываеющего тега </body>)
Как выглядит backend код написанный на php, который отдаёт нам необходимые элементы для вставки:
Обработчик:
Шаблон (get.tpl):
где:
Читая различные маны(stackoverflow и др.) по вставке элементов в html с использованием js, железно работает только document.write. Но на этом вся история ещё не останавливается, на данный момент у нас только получилось загрузить к нам на сайт *.css, *.js, но нам также для вывода нашего виджета потребуется много html разметки, и тут стали приходить различные варианты!
Директива Angular поддерживает следующий template:
#1
#2
Комментарий к #1:
Не кроссдоменное решение, он забирает методом GET .html разметку и выпадают ошибки вида:
посмотрим что скажет на это stackoverflow
Комментарий к #2:
Здесь понятно, что внутри нашего /tracker.js мы не прибегаем к загрузке html с другого источника, а у нас есть возможность вставить его просто в параметр template, супер! Но казалось бы как так? Разве мы не можем сделать кроссдоменный запрос типа JSONP и забрать HTML, подумали вы? НЕТ!
Смотрим сюда stackoverflow
Просто замечтательно!
Инструменты напоследок:
Для сжатия я использовал следующий конфигурационный файл gulp.js
Комментарий: при сжатии html символ одинарной кавычки экранируйте при использовании с ng-class={\'test-class\': expression}, и следите за символами в регулярных выражениях, js-редактор обычно подсвечивает, подсвеченные символы экранируйте
Для копирования кода в буфер я использовал следующий код, расположенный на stackoverflow
Заключение:
Хотелось бы отметить для более точного понимания, данный код работает на любых сайтах, а не только на локальном! Запросы, которыми я обмениваюсь со своим сервером исключительно JSONP!
Всем удачи в разработке!
Суть задачи заключалась в следующем:
- 1. Разработать удобный для заказчика и клиента виджет средства связи
- 2. Оперативно и быстро написать его
- 3. С поддержкой Cross Domain requests
- 4. С быстрой установкой в одну строчку кода
- 5. Быстро настраиваемый
- 6. E-mail рассылка
Решение:
Перед тем как начать писать код, я продумал архитектуру и из самых простых инструментов для backend я использовал php, а front-end native js + angular без использования других
Я не хочу писать огромные куски кода логики, которые каждый разработчик в силах додумать, а хотел бы отметить те моменты, на которые я потратил больше всего времени, хотя и в веб-разработке уже не первый год.
Приступим к разбору узких мест!
Как выглядит код для вставки на сайт (
<script type="text/javascript" charset="utf-8" src="http://domain.ru/widget-get?key=a3234cc36aa23123456a59c281e51e50"></script>
(key — это сгенерированный md5 ключ, по которому я получаю всю информацию по виджету, а не по ID это очень важно, а рекомендуемое место вставки это до закрываеющего тега </body>)
Как выглядит backend код написанный на php, который отдаёт нам необходимые элементы для вставки:
Обработчик:
<?php
class ControllerWidgetGet extends Controller {
public function index(){
if (isset($this->request->get['key'])){
$data['key'] = $this->db->escape($this->request->get['key']);
if ($row = $this->checkValidKey($data['key'])){
$data['row'] = $row;
$this->response->setOutput($this->load->view('/widget/get.tpl', $data));
}else{
echo 'alert("Проверьте правильность вашего ключа");';
}
}
}
public function checkValidKey($key){
$query_key = $service = $this->db->query("SELECT * FROM `" . DB_PREFIX . "widget` WHERE `key_get` = '" . $key . "'");
return $query_key->row;
}
}
Шаблон (get.tpl):
document.write('<link href="http://domain.ru/widget/production/tracker.css" rel="stylesheet"/><script src="http://yastatic.net/angularjs/1.3.16/angular.min.js"></script><script src="http://domain.ru/widget/production/tracker.js"></script><div ng-app="widgetApp"><widget scolor="<?=$row['s_color'];?>" spoints="<?=$row['s_points'];?>" spmenu="<?=$row['s_p_menu'];?>" spwidget="<?=$row['s_p_widget'];?>" sworktime="<?=$row['s_work_time'];?>" key="<?=$key;?>"></widget></div>');
где:
<link href="http://domain.ru/widget/production/tracker.css" rel="stylesheet"/> - наши стили
<script src="http://yastatic.net/angularjs/1.3.16/angular.min.js"></script> - cdn используемая библиотека
<script src="http://domain.ru/widget/production/tracker.js"></script> - логика нашего приложения
<div ng-app="widgetApp"><widget scolor="<?=$row['s_color'];?>" spoints="<?=$row['s_points'];?>" spmenu="<?=$row['s_p_menu'];?>" spwidget="<?=$row['s_p_widget'];?>" sworktime="<?=$row['s_work_time'];?>" key="<?=$key;?>"></widget></div> - инициализация нашего angular приложения, с передаваемыми параметрами в Виджет
Читая различные маны(
Директива Angular поддерживает следующий template:
#1
.directive('myDialog', function() {
return {
templateUrl: 'http://domain.ru/my-dialog.html'
};
#2
.directive('myDialog', function() {
return {
template: '<div ng-controller="MyController"><h1>{{textHello}}</h1></div>'
};
Комментарий к #1:
Не кроссдоменное решение, он забирает методом GET .html разметку и выпадают ошибки вида:
“No 'Access-Control-Allow-Origin' header is present on the requested resource”
посмотрим что скажет на это stackoverflow
Комментарий к #2:
Здесь понятно, что внутри нашего /tracker.js мы не прибегаем к загрузке html с другого источника, а у нас есть возможность вставить его просто в параметр template, супер! Но казалось бы как так? Разве мы не можем сделать кроссдоменный запрос типа JSONP и забрать HTML, подумали вы? НЕТ!
Смотрим сюда stackoverflow
Просто замечтательно!
Инструменты напоследок:
Для сжатия я использовал следующий конфигурационный файл gulp.js
var gulp = require('gulp'),
minifyHTML = require('gulp-minify-html'),
sass = require('gulp-sass');
autoprefixer = require('gulp-autoprefixer'),
minifycss = require('gulp-minify-css'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
gulp.task('p-ht', function() {
var opts = {
conditionals: true,
spare:true
};
return gulp.src('src/html/index.html')
.pipe(minifyHTML(opts))
.pipe(gulp.dest('dest/html/'))
});
gulp.task('p-st', function() {
//return gulp.src('src/styles/main.scss')
//.pipe(sass({style: 'expanded'}))
return gulp.src('src/styles/tracker.css')
.pipe(autoprefixer('last 2 version'))
.pipe(gulp.dest('dest/styles/'))
//.pipe(rename({suffix: '.min'} ))
.pipe(minifycss())
.pipe(gulp.dest('dest/styles/'))
});
gulp.task('p-sc', function() {
return gulp.src('src/scripts/*.js')
.pipe(concat('tracker.js'))
.pipe(gulp.dest('dest/scripts/'))
//.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('dest/scripts/'))
});
gulp.task('watch', function() {
gulp.watch('src/scripts/*.js', ['p-sc'])
});
gulp.task('dev', ['p-st', 'p-sc', 'watch'], function () {
});
gulp.task('build', ['p-st', 'p-sc', 'p-ht'], function () {
});
Комментарий: при сжатии html символ одинарной кавычки экранируйте при использовании с ng-class={\'test-class\': expression}, и следите за символами в регулярных выражениях, js-редактор обычно подсвечивает, подсвеченные символы экранируйте
Для копирования кода в буфер я использовал следующий код, расположенный на stackoverflow
Заключение:
Хотелось бы отметить для более точного понимания, данный код работает на любых сайтах, а не только на локальном! Запросы, которыми я обмениваюсь со своим сервером исключительно JSONP!
Всем удачи в разработке!
Комментарии (5)
sHinE
06.08.2015 16:31Браузеры на https страницах не будут ругаться на вставку скриптов и стилей по http? Можно для доступа по протоколу загруженной страницы начинать адреса с
//
— типа//domain.ru/widget/production/tracker.js
DmitryMV
06.08.2015 17:48Идея хорошая, но на данный момент буду тестировать CDN на Amazon CloudFront и скоро подготовлю новую статью!
antirek
10.08.2015 07:06В виде кода на гитхабе было бы удобнее изучить ваше решение и взять его на вооружение.
Названия задач в gulpfile доставляют. Вам самому удобно их различать?
rsvasilyev
Вы хоть бы вкратце объяснили, что такое «Oblax» и что значит «виджет средства связи».
DmitryMV
Callback — это обратный звонок с сайта, т.е. клиент который решил посетить вашу страницу не смог найти необходимую ему информацию и он уже готов выйти с сайта, но вдруг Callback — виджет, это кнопка с фиксированными положением на странице экрана, нажав на которую или же поймав клиента на одном из сценариев (прокрутка в низ страницы, при входе на сайт), открывается форма в которой клиент имеет возможность выбрав удобное время и оставив телефон Заказать обратный звонок!