Skip to content

Commit 434e25c

Browse files
committed
First Commit
1 parent 7bfdf22 commit 434e25c

File tree

10 files changed

+324
-6
lines changed

10 files changed

+324
-6
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/meat-source

LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) 2013 Tivix, Inc.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be
12+
included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

MANIFEST.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
include AUTHORS
2+
include LICENSE
3+
include MANIFEST.in
4+
include README.rst
5+
include README-RUS.rst

README-RUS.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# django-template-include-ajax
2+
3+
Назначение: django-Тег, на подобии стандартного `{% include 'template.html' %}` для отложенной загрузки шаблона через
4+
ajax.При этом шаблон оборачивается в `<div>` Поддерживает, как внутренние так и внешние скрипты в шаблоне (через
5+
html-тег `<sсript>`). Имеет необязательное условие на
6+
минимальную и максимальную ширину экрана, при котором загружается шаблон. Они используется для отделения мобильной,
7+
десктопной и планшетной версий шаблона). Также имеет необязательный аргумент `delWrap`,
8+
который убирает обертку вокруг содержимого. По умолчанию отключен.(при включении не дает загрузится внешним скриптам).
9+
10+
Этот код не имеет смысла оборачивать в отдельное приложение django. Более целесообразно будет внедрить данный тег
11+
непосредственно в ваш проект.
12+
13+
зависимостей не имеет
14+
15+
## Работа
16+
После загрузки в шаблоне тега `{% load template_include_ajax %}`
17+
загружаем шаблон через ajax, где example.html имя шаблона
18+
```
19+
{% include_ajax 'example.html' %}
20+
```
21+
если шаблон во вложенной папке, то указываем её
22+
```
23+
{% include_ajax 'folder/example.html' %}
24+
```
25+
также вы можете указать дополнительные параметры minWidth и maxWidth, за пределами которых ajax срабатывать не будет.
26+
```
27+
{% include_ajax 'example_only_tablet.html' minWidth='576' maxWidth='1025' %}
28+
```
29+
Есть еще дополнительный параметр delWrap, который убирает обертку вокруг содержимого.По умолчанию отключен.
30+
(при включении не дает загрузится внешним скриптам).
31+
```
32+
{% include_ajax 'example_not_wrap.html' delWrap='True' %}
33+
```
34+
### Установка
35+
В вашем приложении создаем папку templatetags с файлом include_ajax. Далее в urls проекта добавляем
36+
```
37+
path('include-ajax/<template>', include_ajax),
38+
```
39+
40+
подключаем обработку в views
41+
42+
```
43+
def include_ajax(request, template):
44+
template = template.replace('&', '/') # для шаблонов вложенных в папку
45+
try:
46+
return render(request, template)
47+
except TemplateDoesNotExist:
48+
return HttpResponse(status=404)
49+
```
50+
51+
в шаблоне подгружаем тег
52+
```
53+
{% load template_include_ajax %}
54+
```
55+
Все. Пользуемся.
56+
## Важно:
57+
1) рабочие скрипты после загрузки и исполнения самоудаляются ! (при проверке и отладке вы должны учитывать это)
58+
2) внешние скрипты записываются в конец блока (т.е после данных)
59+
3) ваш шаблон будет обернут в `<div>` вы можете убрать обертку использовав дополнительный параметр delWrap, но при этом
60+
не будут успевать срабатывать внешние скрипты (допустим яндекс карта).
61+
62+
63+
## Запуск тестов
64+
65+
Протестировать работу можно скачав demo и подключив как обычный проект django
66+
67+
68+
## Поспособствовать
69+
70+
Предложения, ошибки в работе и комментарии прошу отправлять на почту ukolovsl88@gmail.com
71+
72+
## Версии
73+
74+
Тестировалось на django 2.1.10 - 2.2.10, но скорее всего будет работать и в более ранних версиях.
75+
76+
## Автор
77+
78+
* **Вячеслав Уколов** - [github.com/meat-source](https://github.com/meat-source)
79+
80+
## Лицензия
81+
82+
Этот проект лицензирован под лицензией MIT - [LICENSE.md](LICENSE.md)
83+

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# django-template-include-ajax
2+
3+
Purpose: django Tag, similar to the standard `{% include 'template.html' %}` for deferred template loading via
4+
ajax.The template is wrapped in `<div>` Supports both internal and external scripts in the template (via
5+
the html tag `<sсript>`). Has an optional condition on
6+
the minimum and maximum screen width for loading the template. They are used for separating mobile,
7+
desktop and tablet versions of the template). It also has an optional `delWrap`argument,
8+
which removes the wrapper around the content. Disabled by default.(when enabled, it does not allow external scripts to
9+
load).
10+
```
11+
{% include_ajax 'example_not_wrap.html' delWrap='True' %}
12+
```
13+
14+
It doesn't make sense to wrap this code in a separate django app. It is more appropriate to implement this tag
15+
directly to your project.
16+
17+
does not have any dependencies
18+
19+
## Getting Started
20+
After loading in the template tag `{% load template_include_ajax %}`
21+
uploading the template via ajax, where example.html template name
22+
``
23+
{% include_ajax 'example.html' %}
24+
``
25+
if the template is in a subfolder, specify it
26+
``
27+
{% include_ajax 'folder/example.html' %}
28+
``
29+
you can also specify additional parameters minWidth and maxWidth, beyond which ajax will not be triggered.
30+
```
31+
{% include_ajax 'example_only_tablet.html' minWidth='576' maxWidth='1025' %}
32+
```
33+
There is also an additional delWrap parameter that removes the wrapper around the content.Disabled by default.
34+
(when enabled, it does not allow external scripts to load).
35+
36+
### Installing
37+
In your app, create a templatetags folder with the include_ajax file. Then in the project urls we add
38+
``
39+
path('include-ajax/<template>', include_ajax),
40+
``
41+
42+
enabling processing in views
43+
44+
``
45+
def include_ajax(request, template):
46+
template = template.replace('&', '/') # for templates that are nested in a folder
47+
try:
48+
return render(request, template)
49+
except TemplateDoesNotExist:
50+
return HttpResponse(status=404)
51+
``
52+
53+
loading the tag in the template
54+
``
55+
{% load template_include_ajax %}
56+
``
57+
Everything. Use.
58+
## Importantly:
59+
1) working scripts are self-deleted after loading and execution ! (you should keep this in mind when checking and debugging)
60+
2) external scripts are written to the end of the block (i.e. after the data)
61+
3) your template will be wrapped in `<div>` you can remove the wrapper by using the additional delWrap parameter, but
62+
external scripts (for example, Yandex map) will not have time to fire.
63+
64+
65+
## Running tests
66+
67+
You can test it by downloading the demo and connecting it as a regular django project
68+
69+
70+
## Contributing
71+
72+
Please send suggestions, errors in the work and comments to the email address ukolovsl88@gmail.com
73+
74+
## Versioning
75+
76+
It was tested on django 2.1.10 - 2.2.10, but it will probably work in earlier versions as well.
77+
78+
## Author
79+
80+
**Slava Ukolov** - [github.com/meat-source](https://github.com/meat-source)
81+
82+
##License
83+
84+
This project is licensed under the MIT license - [LICENSE.md](LICENSE.md)

demo/app/templates/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
{% load tags %}
3+
{% load template_include_ajax %}
44
<head>
55
<meta charset="UTF-8">
66
<title>Demo django-template-include-ajax</title>

demo/app/templatetags/tags.py renamed to demo/app/templatetags/template_include_ajax.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ def include_ajax(template, minWidth='undefined', maxWidth='undefined', delWrap =
1212
котором загружается шаблон. Также имеет необязательный аргумент delWrap, который убирает обертку вокруг содержимого.
1313
По умолчанию отключен.(ПРИ ВКЛЮЧЕНИИ НЕ ДАЕТ ЗАГРУЗИТСЯ ВНЕШНИМ СКРИПТАМ).
1414
15-
тестировалось на django 2.1.10
15+
тестировалось на django 2.1.10 - 2.2.10
1616
Создатель Вячеслав Уколов. вопросы и предложения по почте - (ukolovsl88@gmail.com)
17+
github - https://github.com/meat-source
1718
1819
19-
ВНИМАНИЕ: рабочие скрипты после загрузки и исполнения самоудаляются !
20+
ВНИМАНИЕ: рабочие скрипты после загрузки и исполнения самоудаляются ! (это необходимо учитывать при тестировании и
21+
отладке)
2022
ВНИМАНИЕ №2: внешние скрипты записываются в конец блока (т.е после данных)
21-
ВНИМАНИЕ №3: ваш шаблон будет обернут в <div> вы можете убрать обертку раскомментировав строку ниже, но при этом не
22-
будут успевать срабатывать внешние скрипты (допустим яндекс карта)
23+
ВНИМАНИЕ №3: ваш шаблон будет обернут в <div> вы можете убрать обертку использовав параметр delWrap='True',
24+
но при этом небудут успевать срабатывать внешние скрипты (допустим яндекс карта)
2325
смысл такой: на вход приходит имя шаблона. Допольнительно максимальная и/или минимальная ширина экрана браузера
2426
на выходе <div> с именем шаблона и солью + два скрипта один это ajax (загружает данные) и
2527
onload вешает обработчик событий на конец загрузки страницы с запуском ajax

demo/demo/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from django.contrib import admin
2-
from django.urls import path, include
2+
from django.urls import path
33
from app.views import demo,include_ajax
44

55
urlpatterns = [

readme.txt

Whitespace-only changes.

template_include_ajax.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
from django import template
2+
from django.utils.safestring import mark_safe
3+
4+
register = template.Library()
5+
6+
7+
@register.simple_tag(name='include_ajax')
8+
def include_ajax(template, minWidth='undefined', maxWidth='undefined', delWrap =False):
9+
"""
10+
Назначение: django-Тег для отложенной загрузки шаблона через ajax. Поддерживает, как внутренние так и внешние
11+
скрипты (через html-тег <sсript>). Имеет необязательное условие на минимальную и максимальную ширину экрана, при
12+
котором загружается шаблон. Также имеет необязательный аргумент delWrap, который убирает обертку вокруг содержимого.
13+
По умолчанию отключен.(ПРИ ВКЛЮЧЕНИИ НЕ ДАЕТ ЗАГРУЗИТСЯ ВНЕШНИМ СКРИПТАМ).
14+
15+
тестировалось на django 2.1.10 - 2.2.10
16+
Создатель Вячеслав Уколов. вопросы и предложения по почте - (ukolovsl88@gmail.com)
17+
github - https://github.com/meat-source
18+
19+
20+
ВНИМАНИЕ: рабочие скрипты после загрузки и исполнения самоудаляются ! (это необходимо учитывать при тестировании и
21+
отладке)
22+
ВНИМАНИЕ №2: внешние скрипты записываются в конец блока (т.е после данных)
23+
ВНИМАНИЕ №3: ваш шаблон будет обернут в <div> вы можете убрать обертку использовав параметр delWrap='True',
24+
но при этом небудут успевать срабатывать внешние скрипты (допустим яндекс карта)
25+
смысл такой: на вход приходит имя шаблона. Допольнительно максимальная и/или минимальная ширина экрана браузера
26+
на выходе <div> с именем шаблона и солью + два скрипта один это ajax (загружает данные) и
27+
onload вешает обработчик событий на конец загрузки страницы с запуском ajax
28+
данная функция должна использоваться вместе вьъюхой и урл
29+
вьюха:
30+
def include_ajax(request, template):
31+
template = template.replace('&', '/') # для шаблонов вложенных в папку
32+
try:
33+
return render(request, template)
34+
except TemplateDoesNotExist:
35+
return HttpResponse(status=404)
36+
урл (в проекте!):
37+
path('include-ajax/<template>', include_ajax),
38+
"""
39+
# Функция Include - Ajax - запроса(непосредственно запрос)
40+
import random
41+
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'm', 'i', 'k', 'l', 'o', 'p', 'r', 's', 't', 'n']
42+
# соль
43+
sol = ''.join(map(str, random.sample(a, 5)))
44+
# удаляет скрипты после работы
45+
del_garbage = "document.getElementById('ajax_" + sol + "').remove();document.getElementById('onload_" + sol \
46+
+ "').remove();"
47+
# Если есть аргументы ширины сравниваем с окном браузера и выходим если не подходит
48+
if minWidth != 'undefined' or maxWidth != 'undefined':
49+
mobile_or_destktop = "if (screen.width < " + minWidth + " || screen.width > " \
50+
+ maxWidth + "){" + del_garbage + " return}"
51+
52+
else:
53+
mobile_or_destktop = ''
54+
# выполняет скрипты в теле ajax
55+
execute_script = """function executeScripts (obj){
56+
var head = document.getElementsByTagName('head')[0];
57+
var scripts = obj.getElementsByTagName('script');
58+
59+
for(var i = 0; i < scripts.length; i++){
60+
let str = scripts[i].outerHTML;
61+
let newSrc = str.match(/data-script-src=['"][^'"]*[^"]/gi);
62+
if(newSrc != null){
63+
newSrc = newSrc[0].replace('data-script-src=','');
64+
newSrc = newSrc.replace(/['"]/g,'');
65+
}
66+
eval(scripts[i].innerHTML);
67+
68+
if(newSrc != null){
69+
var script = document.createElement('script');
70+
script.type = 'text/javascript';
71+
script.src = newSrc;
72+
obj.appendChild(script);
73+
//scripts[i].src = '';
74+
}
75+
}
76+
}"""
77+
# Сборка и вставка скриптов после пирнятия ответа серверра
78+
# (block.outerHTML=block.innerHTML убирает обертку, но при этом не успевают сработать внешние скрипты)
79+
if delWrap:
80+
post_send = execute_script + "executeScripts(block);" + del_garbage + "block.outerHTML= block.innerHTML"
81+
else:
82+
post_send = execute_script + "executeScripts(block);" + del_garbage # + "block.outerHTML= block.innerHTML"
83+
84+
# непосредственно сам ajax
85+
include_ajax = """<script id='ajax_""" + sol + """'>
86+
function SendAjax_""" + sol + """(){
87+
""" + mobile_or_destktop + """
88+
var url =document.location.protocol +'//'+ document.location.host
89+
+ '/include-ajax/""" + template.replace('/', '&') + """';
90+
var request = new XMLHttpRequest();
91+
request.open('GET', url);
92+
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
93+
request.addEventListener('readystatechange', () => {
94+
if (request.status === 200 && request.readyState === XMLHttpRequest.DONE) {
95+
var block = document.getElementById('""" + template + """');
96+
function replace_src(str){return str.replace(/src/g,'data-script-src')};
97+
block.innerHTML = request.responseText.replace(/<script.*<\/script>/g, replace_src);
98+
// console.log(block.innerHTML)
99+
console.log( 'include-ajax: подгружен template - ' + '""" + template + """');
100+
""" + post_send + """
101+
}
102+
if (request.status != 200){
103+
console.error( 'include-ajax: подгрузка шаблона не удалась - ' + '""" + template + """ --- '
104+
+ request.status + ' --- ' + request.statusText)
105+
};
106+
});
107+
request.send();
108+
}
109+
</script>"""
110+
# вешаем событие
111+
onload_body = """<script id='onload_""" + sol + """'>
112+
function addEvent_""" + sol + """(elem, type, handler){
113+
if(elem.addEventListener){ elem.addEventListener(type, handler, false);}
114+
else { elem.attachEvent('on'+type, handler);}
115+
return false;
116+
};
117+
addEvent_""" + sol + """(window, 'load', SendAjax_""" + sol + """);
118+
</script>"""
119+
# обертка для будущего блока
120+
block = "<div data-defer-template id='" + template + "'></div>"
121+
response = block + include_ajax + onload_body
122+
123+
return mark_safe(response)

0 commit comments

Comments
 (0)