├── .coveragerc
├── .gitignore
├── .travis.yml
├── CHANGELOG.rst
├── LICENSE.txt
├── MANIFEST.in
├── Makefile
├── README.rst
├── TODO.txt
├── docs
├── Makefile
├── conf.py
├── index.rst
└── make.bat
├── example.gif
├── lazy_tags
├── __init__.py
├── decorators.py
├── static
│ └── img
│ │ └── lazy_tags
│ │ └── spinner.gif
├── templates
│ └── lazy_tags
│ │ ├── lazy_tag.html
│ │ ├── lazy_tags_javascript.html
│ │ ├── lazy_tags_jquery.html
│ │ └── lazy_tags_prototype.html
├── templatetags
│ ├── __init__.py
│ └── lazy_tags.py
├── urls.py
├── utils.py
└── views.py
├── setup.cfg
├── setup.py
└── tests
├── __init__.py
├── models.py
├── requirements.txt
├── settings.py
├── templates
└── tests
│ ├── _tags.html
│ ├── decorator_tag_with_args.html
│ ├── inclusion_tag.html
│ ├── inclusion_tag_with_args.html
│ ├── test_javascript.html
│ ├── test_jquery.html
│ └── test_prototype.html
├── templatetags
├── __init__.py
├── test_tags.py
└── tests
│ ├── __init__.py
│ └── nested_tags.py
├── tests.py
├── urls.py
└── views.py
/.coveragerc:
--------------------------------------------------------------------------------
1 | [report]
2 | exclude_lines =
3 | pragma: no cover
4 |
5 | # Don't complain about missing debug-only code:
6 | def __repr__
7 | if self\.debug
8 |
9 | # Don't complain if tests don't hit defensive assertion code:
10 | raise AssertionError
11 | raise NotImplementedError
12 | except ImportError
13 |
14 | # Don't complain if non-runnable code isn't run:
15 | if 0:
16 | if __name__ == .__main__.:
17 |
18 | show_missing = True
19 | precision = 2
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | build/
3 | src/
4 | pip-log.txt
5 | *DS_Store
6 | *~
7 | dist/
8 | *.egg-info/
9 | avatars
10 | .coverage
11 | docs/_build
12 | tests/test_static/
13 | htmlcov/
14 | *.geany
15 | *.out
16 | .env
17 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - 2.7
4 | - 3.4
5 | - 3.5
6 | - 3.6
7 | install:
8 | - pip install -e .
9 | - pip install -r tests/requirements.txt
10 | - pip install Django==${DJANGO}
11 | script: make test
12 | env:
13 | - DJANGO=1.9.13
14 | - DJANGO=1.10.8
15 | - DJANGO=1.11.9
16 | - DJANGO=2.0.2
17 | matrix:
18 | exclude:
19 | - python: 2.7
20 | env: DJANGO=2.0.2
21 | after_success:
22 | - coveralls
23 |
--------------------------------------------------------------------------------
/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | * 0.5.0 (February 3, 2018)
5 | * Added Django 1.10, 1.11, and 2.0 support.
6 | * Removed Python 3.2 and 3.3 support.
7 | * Removed Django 1.7 and 1.8 support.
8 |
9 | * 0.4.1 (January 17, 2016)
10 | * Made lazy tag URL not hardcoded in JavaScript.
11 | * Fixed Python 3 bug when using lazy_tag decorator.
12 | * Fixed Django 1.9 deprecation warnings.
13 |
14 | * 0.4.0 (December 2, 2015)
15 | * Added Python 3.5 support
16 | * Added Django 1.9 support
17 | * Removed Python 2.6 support
18 | * Removed Django 1.4, 1.5, and 1.6 support
19 |
20 | * 0.3.1 (August 9, 2015)
21 | * Works with template tags in subpackages, e.g. {% load foo.bar %}
22 |
23 | * 0.3.0 (August 3, 2015)
24 | * Add lazy_tag decorator.
25 | * Added setting to use jQuery, Prototype, or pure JavaScript for AJAX
26 |
27 | * 0.2.1-0.2.3 (July 31, 2015)
28 | * Fixed MANIFEST.in [#]_
29 |
30 | * 0.2.0 (July 30, 2015)
31 | * Use Django cache instead of URL parameters in order to prevent potential remote code execution.
32 | * Fixed issue where tags with multiple args would not work.
33 | * Removed template tag args/kwargs always being passed in as strings.
34 | * Removed LAZY_TAGS_FORCE_LOGIN setting. Not needed now that remote code execution issue is fixed.
35 |
36 | * 0.1 (July 28, 2015)
37 | * Initial alpha release
38 |
39 | .. [#] `"Every Python project has a "Fix MANIFEST.in" commit. Look it up, it’s true." `_
40 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Grant McConnaughey
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README.rst
2 | include LICENSE.txt
3 | recursive-include docs *
4 | recursive-include lazy_tags/static *
5 | recursive-include lazy_tags/templates *.html
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | export DJANGO_SETTINGS_MODULE=tests.settings
2 | export PYTHONPATH=.
3 |
4 | .PHONY: test
5 |
6 | test:
7 | flake8 lazy_tags
8 | coverage run --source=lazy_tags `which django-admin.py` test tests
9 | coverage report
10 |
11 | publish: clean
12 | python setup.py sdist bdist_wheel
13 | twine upload dist/*
14 |
15 | clean:
16 | rm -vrf ./build ./dist ./*.egg-info
17 | find . -name '*.pyc' -delete
18 | find . -name '*.tgz' -delete
19 |
20 | runserver:
21 | `which django-admin.py` runserver
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | django-lazy-tags
2 | ================
3 |
4 | .. image:: https://img.shields.io/pypi/v/django-lazy-tags.svg
5 | :target: https://pypi.python.org/pypi/django-lazy-tags
6 |
7 | .. image:: https://readthedocs.org/projects/django-lazy-tags/badge/?version=latest
8 | :target: http://django-lazy-tags.readthedocs.org/en/latest/
9 | :alt: Documentation Status
10 |
11 | .. image:: https://travis-ci.org/grantmcconnaughey/django-lazy-tags.svg
12 | :target: https://travis-ci.org/grantmcconnaughey/django-lazy-tags
13 |
14 | .. image:: https://coveralls.io/repos/grantmcconnaughey/django-lazy-tags/badge.svg?branch=master&service=github
15 | :target: https://coveralls.io/github/grantmcconnaughey/django-lazy-tags?branch=master
16 |
17 | A Django app for easily loading template tags via AJAX.
18 |
19 | Installation
20 | ------------
21 |
22 | 1\. Install via pip
23 |
24 | .. code-block:: python
25 |
26 | pip install django-lazy-tags
27 |
28 | 2\. Add to installed apps
29 |
30 | .. code-block:: python
31 |
32 | INSTALLED_APPS = (
33 | # ...
34 | 'lazy_tags',
35 | )
36 |
37 | 3\. Add the lazy tags urls to your root urlconf.
38 |
39 | .. code-block:: python
40 |
41 | urlpatterns = patterns('',
42 | # ...
43 | url(r'^lazy_tags/', include('lazy_tags.urls')),
44 | )
45 |
46 | Usage
47 | -----
48 |
49 | First, load the ``lazy_tags`` library in your templates.
50 |
51 | .. code-block:: django
52 |
53 | {% load lazy_tags %}
54 |
55 | Then, call the ``lazy_tag`` template tag passing your tag name as the first parameter. The format is ``tag_library.tag_name`` where ``tag_library`` is what you would load at the top of the page (e.g. ``my_tags``) and ``tag_name`` is the name of your template tag (e.g. ``my_template_tag``). After the first argument to ``lazy_tag`` simply pass the rest of the args and kwargs just as you would pass them to your own tag.
56 |
57 | This:
58 |
59 | .. code-block:: django
60 |
61 | {% load my_tags %}
62 |
63 | {% my_template_tag arg1 arg2 kw1='hello' kw2='world' %}
64 |
65 | Becomes this:
66 |
67 | .. code-block:: django
68 |
69 | {% load lazy_tags %}
70 |
71 | {% lazy_tag 'my_tags.my_template_tag' arg1 arg2 kw1='hello' kw2='world' %}
72 |
73 | After placing your template tags in the template you still need to specify where you would like the AJAX JavaScript to output to the page. That is what the ``lazy_tags_js`` tag is for:
74 |
75 | .. code-block:: django
76 |
77 | {% block js-additional %}
78 | {% lazy_tags_js%}
79 | {% endblock %}
80 |
81 | This will spit out the JavaScript required to run the AJAX. The JavaScript changes depending on your ``LAZY_TAGS_AJAX_JS`` setting.
82 |
83 | The lazy_tag decorator
84 | ----------------------
85 |
86 | django-lazy-tags also includes a decorator that can be used on template tags that use ``simple_tag``. When using the ``lazy_tag`` decorator you can use your template tags exactly the same as before and they will use AJAX.
87 |
88 | .. code-block:: python
89 |
90 | from lazy_tags.decorators import lazy_tag
91 |
92 | @register.simple_tag
93 | @lazy_tag
94 | def show_user(pk):
95 | user = User.objects.get(pk=pk)
96 | return render_to_string('user/show_user.html', {
97 | 'user': user,
98 | })
99 |
100 | There are a few caveats with this method. First, the decorator currently only works with tags that use ``simple_tag``. Hopefully this will work with ``inclusion_tag`` in the future. Secondly, the ``lazy_tag`` decorator must come *after* the ``simple_tag`` decorator.
101 |
102 | Settings
103 | --------
104 |
105 | LAZY_TAGS_AJAX_JS
106 | The library to use to run AJAX. Options are ``'javascript'``, ``'jquery'``, or ``'prototype'``. Defaults to ``'jquery'``.
107 |
108 | LAZY_TAGS_CACHE_TIMEOUT
109 | The timeout on each lazy tag cache. Defaults to ``60`` (seconds).
110 |
111 | LAZY_TAGS_ERROR_MESSAGE
112 | The error message to display if the AJAX request fails. Defaults to ``'An error occurred.'``
113 |
114 | Customizing the Loading Animation
115 | ---------------------------------
116 |
117 | This is the default HTML on the page before the AJAX request completes:
118 |
119 | .. code-block:: html
120 |
121 |
122 |
124 |
127 |
128 |
129 |
130 | To customize the loading animation, override the ``lazy-tag``, ``lazy-tag-spinner-container``, or ``lazy-tag-spinner`` classes in your CSS.
131 |
132 |
133 | Current Limitations
134 | -------------------
135 |
136 | * Does not work with tags that take context.
137 | * Template tag arguments must be serializable (str, unicode, int, float, etc.).
138 |
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | Soon
2 | * Make lazy_tag decorator work with inclusion_tag
3 | * Transparent AJAX spinner
4 |
5 | Someday
6 | * Work with a tag where takes_context = True
7 | * Work with Django models, not just pks
8 | * Send csrf_token
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
21 |
22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
23 |
24 | help:
25 | @echo "Please use \`make ' where is one of"
26 | @echo " html to make standalone HTML files"
27 | @echo " dirhtml to make HTML files named index.html in directories"
28 | @echo " singlehtml to make a single large HTML file"
29 | @echo " pickle to make pickle files"
30 | @echo " json to make JSON files"
31 | @echo " htmlhelp to make HTML files and a HTML help project"
32 | @echo " qthelp to make HTML files and a qthelp project"
33 | @echo " applehelp to make an Apple Help Book"
34 | @echo " devhelp to make HTML files and a Devhelp project"
35 | @echo " epub to make an epub"
36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
37 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
39 | @echo " text to make text files"
40 | @echo " man to make manual pages"
41 | @echo " texinfo to make Texinfo files"
42 | @echo " info to make Texinfo files and run them through makeinfo"
43 | @echo " gettext to make PO message catalogs"
44 | @echo " changes to make an overview of all changed/added/deprecated items"
45 | @echo " xml to make Docutils-native XML files"
46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
47 | @echo " linkcheck to check all external links for integrity"
48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
49 | @echo " coverage to run coverage check of the documentation (if enabled)"
50 |
51 | clean:
52 | rm -rf $(BUILDDIR)/*
53 |
54 | html:
55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
56 | @echo
57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
58 |
59 | dirhtml:
60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
61 | @echo
62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
63 |
64 | singlehtml:
65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
66 | @echo
67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
68 |
69 | pickle:
70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
71 | @echo
72 | @echo "Build finished; now you can process the pickle files."
73 |
74 | json:
75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
76 | @echo
77 | @echo "Build finished; now you can process the JSON files."
78 |
79 | htmlhelp:
80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
81 | @echo
82 | @echo "Build finished; now you can run HTML Help Workshop with the" \
83 | ".hhp project file in $(BUILDDIR)/htmlhelp."
84 |
85 | qthelp:
86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
87 | @echo
88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-lazy-tags.qhcp"
91 | @echo "To view the help file:"
92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-lazy-tags.qhc"
93 |
94 | applehelp:
95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
96 | @echo
97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
98 | @echo "N.B. You won't be able to view it unless you put it in" \
99 | "~/Library/Documentation/Help or install it in your application" \
100 | "bundle."
101 |
102 | devhelp:
103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
104 | @echo
105 | @echo "Build finished."
106 | @echo "To view the help file:"
107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/django-lazy-tags"
108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-lazy-tags"
109 | @echo "# devhelp"
110 |
111 | epub:
112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
113 | @echo
114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
115 |
116 | latex:
117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
118 | @echo
119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
121 | "(use \`make latexpdf' here to do that automatically)."
122 |
123 | latexpdf:
124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
125 | @echo "Running LaTeX files through pdflatex..."
126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
128 |
129 | latexpdfja:
130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
131 | @echo "Running LaTeX files through platex and dvipdfmx..."
132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
134 |
135 | text:
136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
137 | @echo
138 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
139 |
140 | man:
141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
142 | @echo
143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
144 |
145 | texinfo:
146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
147 | @echo
148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
149 | @echo "Run \`make' in that directory to run these through makeinfo" \
150 | "(use \`make info' here to do that automatically)."
151 |
152 | info:
153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
154 | @echo "Running Texinfo files through makeinfo..."
155 | make -C $(BUILDDIR)/texinfo info
156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
157 |
158 | gettext:
159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
160 | @echo
161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
162 |
163 | changes:
164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
165 | @echo
166 | @echo "The overview file is in $(BUILDDIR)/changes."
167 |
168 | linkcheck:
169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
170 | @echo
171 | @echo "Link check complete; look for any errors in the above output " \
172 | "or in $(BUILDDIR)/linkcheck/output.txt."
173 |
174 | doctest:
175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
176 | @echo "Testing of doctests in the sources finished, look at the " \
177 | "results in $(BUILDDIR)/doctest/output.txt."
178 |
179 | coverage:
180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
181 | @echo "Testing of coverage in the sources finished, look at the " \
182 | "results in $(BUILDDIR)/coverage/python.txt."
183 |
184 | xml:
185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
186 | @echo
187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
188 |
189 | pseudoxml:
190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
191 | @echo
192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
193 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # django-lazy-tags documentation build configuration file, created by
4 | # sphinx-quickstart on Thu Jul 23 22:39:55 2015.
5 | #
6 | # This file is execfile()d with the current directory set to its
7 | # containing dir.
8 | #
9 | # Note that not all possible configuration values are present in this
10 | # autogenerated file.
11 | #
12 | # All configuration values have a default; values that are commented out
13 | # serve to show the default.
14 |
15 | import sys
16 | import os
17 | import shlex
18 |
19 | # If extensions (or modules to document with autodoc) are in another directory,
20 | # add these directories to sys.path here. If the directory is relative to the
21 | # documentation root, use os.path.abspath to make it absolute, like shown here.
22 | #sys.path.insert(0, os.path.abspath('.'))
23 |
24 | # -- General configuration ------------------------------------------------
25 |
26 | # If your documentation needs a minimal Sphinx version, state it here.
27 | #needs_sphinx = '1.0'
28 |
29 | # Add any Sphinx extension module names here, as strings. They can be
30 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
31 | # ones.
32 | extensions = [
33 | 'sphinx.ext.autodoc',
34 | ]
35 |
36 | # Add any paths that contain templates here, relative to this directory.
37 | templates_path = ['_templates']
38 |
39 | # The suffix(es) of source filenames.
40 | # You can specify multiple suffix as a list of string:
41 | # source_suffix = ['.rst', '.md']
42 | source_suffix = '.rst'
43 |
44 | # The encoding of source files.
45 | #source_encoding = 'utf-8-sig'
46 |
47 | # The master toctree document.
48 | master_doc = 'index'
49 |
50 | # General information about the project.
51 | project = u'django-lazy-tags'
52 | copyright = u'2015, Grant McConnaughey'
53 | author = u'Grant McConnaughey'
54 |
55 | # The version info for the project you're documenting, acts as replacement for
56 | # |version| and |release|, also used in various other places throughout the
57 | # built documents.
58 | #
59 | # The short X.Y version.
60 | version = '0.1'
61 | # The full version, including alpha/beta/rc tags.
62 | release = '0.1'
63 |
64 | # The language for content autogenerated by Sphinx. Refer to documentation
65 | # for a list of supported languages.
66 | #
67 | # This is also used if you do content translation via gettext catalogs.
68 | # Usually you set "language" from the command line for these cases.
69 | language = None
70 |
71 | # There are two options for replacing |today|: either, you set today to some
72 | # non-false value, then it is used:
73 | #today = ''
74 | # Else, today_fmt is used as the format for a strftime call.
75 | #today_fmt = '%B %d, %Y'
76 |
77 | # List of patterns, relative to source directory, that match files and
78 | # directories to ignore when looking for source files.
79 | exclude_patterns = ['_build']
80 |
81 | # The reST default role (used for this markup: `text`) to use for all
82 | # documents.
83 | #default_role = None
84 |
85 | # If true, '()' will be appended to :func: etc. cross-reference text.
86 | #add_function_parentheses = True
87 |
88 | # If true, the current module name will be prepended to all description
89 | # unit titles (such as .. function::).
90 | #add_module_names = True
91 |
92 | # If true, sectionauthor and moduleauthor directives will be shown in the
93 | # output. They are ignored by default.
94 | #show_authors = False
95 |
96 | # The name of the Pygments (syntax highlighting) style to use.
97 | pygments_style = 'sphinx'
98 |
99 | # A list of ignored prefixes for module index sorting.
100 | #modindex_common_prefix = []
101 |
102 | # If true, keep warnings as "system message" paragraphs in the built documents.
103 | #keep_warnings = False
104 |
105 | # If true, `todo` and `todoList` produce output, else they produce nothing.
106 | todo_include_todos = False
107 |
108 |
109 | # -- Options for HTML output ----------------------------------------------
110 |
111 | # The theme to use for HTML and HTML Help pages. See the documentation for
112 | # a list of builtin themes.
113 | html_theme = 'default'
114 |
115 | # Theme options are theme-specific and customize the look and feel of a theme
116 | # further. For a list of options available for each theme, see the
117 | # documentation.
118 | #html_theme_options = {}
119 |
120 | # Add any paths that contain custom themes here, relative to this directory.
121 | #html_theme_path = []
122 |
123 | # The name for this set of Sphinx documents. If None, it defaults to
124 | # " v documentation".
125 | #html_title = None
126 |
127 | # A shorter title for the navigation bar. Default is the same as html_title.
128 | #html_short_title = None
129 |
130 | # The name of an image file (relative to this directory) to place at the top
131 | # of the sidebar.
132 | #html_logo = None
133 |
134 | # The name of an image file (within the static path) to use as favicon of the
135 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
136 | # pixels large.
137 | #html_favicon = None
138 |
139 | # Add any paths that contain custom static files (such as style sheets) here,
140 | # relative to this directory. They are copied after the builtin static files,
141 | # so a file named "default.css" will overwrite the builtin "default.css".
142 | html_static_path = ['_static']
143 |
144 | # Add any extra paths that contain custom files (such as robots.txt or
145 | # .htaccess) here, relative to this directory. These files are copied
146 | # directly to the root of the documentation.
147 | #html_extra_path = []
148 |
149 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
150 | # using the given strftime format.
151 | #html_last_updated_fmt = '%b %d, %Y'
152 |
153 | # If true, SmartyPants will be used to convert quotes and dashes to
154 | # typographically correct entities.
155 | #html_use_smartypants = True
156 |
157 | # Custom sidebar templates, maps document names to template names.
158 | #html_sidebars = {}
159 |
160 | # Additional templates that should be rendered to pages, maps page names to
161 | # template names.
162 | #html_additional_pages = {}
163 |
164 | # If false, no module index is generated.
165 | #html_domain_indices = True
166 |
167 | # If false, no index is generated.
168 | #html_use_index = True
169 |
170 | # If true, the index is split into individual pages for each letter.
171 | #html_split_index = False
172 |
173 | # If true, links to the reST sources are added to the pages.
174 | #html_show_sourcelink = True
175 |
176 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
177 | #html_show_sphinx = True
178 |
179 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
180 | #html_show_copyright = True
181 |
182 | # If true, an OpenSearch description file will be output, and all pages will
183 | # contain a tag referring to it. The value of this option must be the
184 | # base URL from which the finished HTML is served.
185 | #html_use_opensearch = ''
186 |
187 | # This is the file name suffix for HTML files (e.g. ".xhtml").
188 | #html_file_suffix = None
189 |
190 | # Language to be used for generating the HTML full-text search index.
191 | # Sphinx supports the following languages:
192 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
193 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
194 | #html_search_language = 'en'
195 |
196 | # A dictionary with options for the search language support, empty by default.
197 | # Now only 'ja' uses this config value
198 | #html_search_options = {'type': 'default'}
199 |
200 | # The name of a javascript file (relative to the configuration directory) that
201 | # implements a search results scorer. If empty, the default will be used.
202 | #html_search_scorer = 'scorer.js'
203 |
204 | # Output file base name for HTML help builder.
205 | htmlhelp_basename = 'django-lazy-tagsdoc'
206 |
207 | # -- Options for LaTeX output ---------------------------------------------
208 |
209 | latex_elements = {
210 | # The paper size ('letterpaper' or 'a4paper').
211 | #'papersize': 'letterpaper',
212 |
213 | # The font size ('10pt', '11pt' or '12pt').
214 | #'pointsize': '10pt',
215 |
216 | # Additional stuff for the LaTeX preamble.
217 | #'preamble': '',
218 |
219 | # Latex figure (float) alignment
220 | #'figure_align': 'htbp',
221 | }
222 |
223 | # Grouping the document tree into LaTeX files. List of tuples
224 | # (source start file, target name, title,
225 | # author, documentclass [howto, manual, or own class]).
226 | latex_documents = [
227 | (master_doc, 'django-lazy-tags.tex', u'django-lazy-tags Documentation',
228 | u'Grant McConnaughey', 'manual'),
229 | ]
230 |
231 | # The name of an image file (relative to this directory) to place at the top of
232 | # the title page.
233 | #latex_logo = None
234 |
235 | # For "manual" documents, if this is true, then toplevel headings are parts,
236 | # not chapters.
237 | #latex_use_parts = False
238 |
239 | # If true, show page references after internal links.
240 | #latex_show_pagerefs = False
241 |
242 | # If true, show URL addresses after external links.
243 | #latex_show_urls = False
244 |
245 | # Documents to append as an appendix to all manuals.
246 | #latex_appendices = []
247 |
248 | # If false, no module index is generated.
249 | #latex_domain_indices = True
250 |
251 |
252 | # -- Options for manual page output ---------------------------------------
253 |
254 | # One entry per manual page. List of tuples
255 | # (source start file, name, description, authors, manual section).
256 | man_pages = [
257 | (master_doc, 'django-lazy-tags', u'django-lazy-tags Documentation',
258 | [author], 1)
259 | ]
260 |
261 | # If true, show URL addresses after external links.
262 | #man_show_urls = False
263 |
264 |
265 | # -- Options for Texinfo output -------------------------------------------
266 |
267 | # Grouping the document tree into Texinfo files. List of tuples
268 | # (source start file, target name, title, author,
269 | # dir menu entry, description, category)
270 | texinfo_documents = [
271 | (master_doc, 'django-lazy-tags', u'django-lazy-tags Documentation',
272 | author, 'django-lazy-tags', 'A Django app for loading template tags over AJAX after a page has loaded.',
273 | 'Miscellaneous'),
274 | ]
275 |
276 | # Documents to append as an appendix to all manuals.
277 | #texinfo_appendices = []
278 |
279 | # If false, no module index is generated.
280 | #texinfo_domain_indices = True
281 |
282 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
283 | #texinfo_show_urls = 'footnote'
284 |
285 | # If true, do not generate a @detailmenu in the "Top" node's menu.
286 | #texinfo_no_detailmenu = False
287 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../README.rst
2 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | set I18NSPHINXOPTS=%SPHINXOPTS% .
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 | echo. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. xml to make Docutils-native XML files
37 | echo. pseudoxml to make pseudoxml-XML files for display purposes
38 | echo. linkcheck to check all external links for integrity
39 | echo. doctest to run all doctests embedded in the documentation if enabled
40 | echo. coverage to run coverage check of the documentation if enabled
41 | goto end
42 | )
43 |
44 | if "%1" == "clean" (
45 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
46 | del /q /s %BUILDDIR%\*
47 | goto end
48 | )
49 |
50 |
51 | REM Check if sphinx-build is available and fallback to Python version if any
52 | %SPHINXBUILD% 2> nul
53 | if errorlevel 9009 goto sphinx_python
54 | goto sphinx_ok
55 |
56 | :sphinx_python
57 |
58 | set SPHINXBUILD=python -m sphinx.__init__
59 | %SPHINXBUILD% 2> nul
60 | if errorlevel 9009 (
61 | echo.
62 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
63 | echo.installed, then set the SPHINXBUILD environment variable to point
64 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
65 | echo.may add the Sphinx directory to PATH.
66 | echo.
67 | echo.If you don't have Sphinx installed, grab it from
68 | echo.http://sphinx-doc.org/
69 | exit /b 1
70 | )
71 |
72 | :sphinx_ok
73 |
74 |
75 | if "%1" == "html" (
76 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
77 | if errorlevel 1 exit /b 1
78 | echo.
79 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
80 | goto end
81 | )
82 |
83 | if "%1" == "dirhtml" (
84 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
85 | if errorlevel 1 exit /b 1
86 | echo.
87 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
88 | goto end
89 | )
90 |
91 | if "%1" == "singlehtml" (
92 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
93 | if errorlevel 1 exit /b 1
94 | echo.
95 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
96 | goto end
97 | )
98 |
99 | if "%1" == "pickle" (
100 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
101 | if errorlevel 1 exit /b 1
102 | echo.
103 | echo.Build finished; now you can process the pickle files.
104 | goto end
105 | )
106 |
107 | if "%1" == "json" (
108 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
109 | if errorlevel 1 exit /b 1
110 | echo.
111 | echo.Build finished; now you can process the JSON files.
112 | goto end
113 | )
114 |
115 | if "%1" == "htmlhelp" (
116 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
117 | if errorlevel 1 exit /b 1
118 | echo.
119 | echo.Build finished; now you can run HTML Help Workshop with the ^
120 | .hhp project file in %BUILDDIR%/htmlhelp.
121 | goto end
122 | )
123 |
124 | if "%1" == "qthelp" (
125 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
126 | if errorlevel 1 exit /b 1
127 | echo.
128 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
129 | .qhcp project file in %BUILDDIR%/qthelp, like this:
130 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-lazy-tags.qhcp
131 | echo.To view the help file:
132 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-lazy-tags.ghc
133 | goto end
134 | )
135 |
136 | if "%1" == "devhelp" (
137 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
138 | if errorlevel 1 exit /b 1
139 | echo.
140 | echo.Build finished.
141 | goto end
142 | )
143 |
144 | if "%1" == "epub" (
145 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
146 | if errorlevel 1 exit /b 1
147 | echo.
148 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
149 | goto end
150 | )
151 |
152 | if "%1" == "latex" (
153 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
154 | if errorlevel 1 exit /b 1
155 | echo.
156 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
157 | goto end
158 | )
159 |
160 | if "%1" == "latexpdf" (
161 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
162 | cd %BUILDDIR%/latex
163 | make all-pdf
164 | cd %~dp0
165 | echo.
166 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
167 | goto end
168 | )
169 |
170 | if "%1" == "latexpdfja" (
171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
172 | cd %BUILDDIR%/latex
173 | make all-pdf-ja
174 | cd %~dp0
175 | echo.
176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
177 | goto end
178 | )
179 |
180 | if "%1" == "text" (
181 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
182 | if errorlevel 1 exit /b 1
183 | echo.
184 | echo.Build finished. The text files are in %BUILDDIR%/text.
185 | goto end
186 | )
187 |
188 | if "%1" == "man" (
189 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
190 | if errorlevel 1 exit /b 1
191 | echo.
192 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
193 | goto end
194 | )
195 |
196 | if "%1" == "texinfo" (
197 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
198 | if errorlevel 1 exit /b 1
199 | echo.
200 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
201 | goto end
202 | )
203 |
204 | if "%1" == "gettext" (
205 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
206 | if errorlevel 1 exit /b 1
207 | echo.
208 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
209 | goto end
210 | )
211 |
212 | if "%1" == "changes" (
213 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
214 | if errorlevel 1 exit /b 1
215 | echo.
216 | echo.The overview file is in %BUILDDIR%/changes.
217 | goto end
218 | )
219 |
220 | if "%1" == "linkcheck" (
221 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
222 | if errorlevel 1 exit /b 1
223 | echo.
224 | echo.Link check complete; look for any errors in the above output ^
225 | or in %BUILDDIR%/linkcheck/output.txt.
226 | goto end
227 | )
228 |
229 | if "%1" == "doctest" (
230 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
231 | if errorlevel 1 exit /b 1
232 | echo.
233 | echo.Testing of doctests in the sources finished, look at the ^
234 | results in %BUILDDIR%/doctest/output.txt.
235 | goto end
236 | )
237 |
238 | if "%1" == "coverage" (
239 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
240 | if errorlevel 1 exit /b 1
241 | echo.
242 | echo.Testing of coverage in the sources finished, look at the ^
243 | results in %BUILDDIR%/coverage/python.txt.
244 | goto end
245 | )
246 |
247 | if "%1" == "xml" (
248 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
249 | if errorlevel 1 exit /b 1
250 | echo.
251 | echo.Build finished. The XML files are in %BUILDDIR%/xml.
252 | goto end
253 | )
254 |
255 | if "%1" == "pseudoxml" (
256 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
257 | if errorlevel 1 exit /b 1
258 | echo.
259 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
260 | goto end
261 | )
262 |
263 | :end
264 |
--------------------------------------------------------------------------------
/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grantmcconnaughey/django-lazy-tags/c24872c1d9f198abd20669c77380a923092374c2/example.gif
--------------------------------------------------------------------------------
/lazy_tags/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = '0.5.0'
2 |
--------------------------------------------------------------------------------
/lazy_tags/decorators.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 |
3 | from django.conf import settings
4 | from django.template.loader import render_to_string
5 | from django.utils import six
6 |
7 | from .utils import get_tag_id, set_lazy_tag_data
8 |
9 |
10 | def _get_func_name(func):
11 | if six.PY2:
12 | return func.func_name
13 | else:
14 | return func.__name__
15 |
16 |
17 | def lazy_tag(func=None):
18 | @wraps(func)
19 | def wrapper(*args, **kwargs):
20 | render_tag = kwargs.pop('render_tag', False)
21 |
22 | if render_tag:
23 | return func(*args, **kwargs)
24 | else:
25 | # Set render_tag in the kwargs so the tag will be rendered next
26 | # time this is called
27 | tag_lib = func.__module__.partition('templatetags.')[-1]
28 | tag_name = _get_func_name(func)
29 | tag = tag_lib + '.' + tag_name
30 | kwargs['render_tag'] = True
31 | tag_id = get_tag_id()
32 | set_lazy_tag_data(tag_id, tag, args, kwargs)
33 |
34 | return render_to_string('lazy_tags/lazy_tag.html', {
35 | 'tag_id': tag_id,
36 | 'STATIC_URL': settings.STATIC_URL,
37 | })
38 | return wrapper
39 |
--------------------------------------------------------------------------------
/lazy_tags/static/img/lazy_tags/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grantmcconnaughey/django-lazy-tags/c24872c1d9f198abd20669c77380a923092374c2/lazy_tags/static/img/lazy_tags/spinner.gif
--------------------------------------------------------------------------------
/lazy_tags/templates/lazy_tags/lazy_tag.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/lazy_tags/templates/lazy_tags/lazy_tags_javascript.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lazy_tags/templates/lazy_tags/lazy_tags_jquery.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lazy_tags/templates/lazy_tags/lazy_tags_prototype.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lazy_tags/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grantmcconnaughey/django-lazy-tags/c24872c1d9f198abd20669c77380a923092374c2/lazy_tags/templatetags/__init__.py
--------------------------------------------------------------------------------
/lazy_tags/templatetags/lazy_tags.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from django.template.loader import render_to_string
3 | from django.conf import settings
4 |
5 | from ..utils import get_tag_id, set_lazy_tag_data
6 |
7 |
8 | register = template.Library()
9 |
10 |
11 | @register.simple_tag
12 | def lazy_tag(tag, *args, **kwargs):
13 | """
14 | Lazily loads a template tag after the page has loaded. Requires jQuery
15 | (for now).
16 |
17 | Usage:
18 | {% load lazy_tags %}
19 |
20 | {% lazy_tag 'tag_lib.tag_name' arg1 arg2 kw1='test' kw2='hello' %}
21 |
22 | Args:
23 | tag (str): the tag library and tag name separated by a period. For a
24 | template tag named `do_thing` in a tag library named `thing_tags`
25 | the `tag` argument would be `'thing_tags.doc_thing'`.
26 | *args: arguments to be passed to the template tag.
27 | **kwargs: keyword arguments to be passed to the template tag.
28 | """
29 | tag_id = get_tag_id()
30 | set_lazy_tag_data(tag_id, tag, args, kwargs)
31 |
32 | return render_to_string('lazy_tags/lazy_tag.html', {
33 | 'tag_id': tag_id,
34 | 'STATIC_URL': settings.STATIC_URL,
35 | })
36 |
37 |
38 | def _render_js(library):
39 | error_message = getattr(settings,
40 | 'LAZY_TAGS_ERROR_MESSAGE',
41 | 'An error occurred.')
42 | template = 'lazy_tags/lazy_tags_{0}.html'.format(library)
43 |
44 | return render_to_string(template, {
45 | 'error_message': error_message,
46 | })
47 |
48 |
49 | @register.simple_tag
50 | def lazy_tags_javascript():
51 | """Outputs the necessary JavaScript to load tags over AJAX."""
52 | return _render_js('javascript')
53 |
54 |
55 | @register.simple_tag
56 | def lazy_tags_jquery():
57 | """Outputs the necessary jQuery to load tags over AJAX."""
58 | return _render_js('jquery')
59 |
60 |
61 | @register.simple_tag
62 | def lazy_tags_prototype():
63 | """Outputs the necessary Prototype to load tags over AJAX."""
64 | return _render_js('prototype')
65 |
66 |
67 | @register.simple_tag
68 | def lazy_tags_js():
69 | """An alias to the JavaScript library specified in settings."""
70 | library = getattr(settings, 'LAZY_TAGS_AJAX_JS', 'jquery')
71 | return _render_js(library.lower())
72 |
--------------------------------------------------------------------------------
/lazy_tags/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 |
3 | from .views import tag
4 |
5 | urlpatterns = [
6 | url(r'^tag/(?P.+)?$', tag, name='lazy_tag'),
7 | ]
8 |
--------------------------------------------------------------------------------
/lazy_tags/utils.py:
--------------------------------------------------------------------------------
1 | import uuid
2 |
3 | from django.conf import settings
4 | from django.core.cache import cache
5 | from django.utils import six
6 |
7 |
8 | def get_tag_id():
9 | return str(uuid.uuid4())
10 |
11 |
12 | def get_cache_key(tag_id):
13 | """Returns a cache key based on a tag id"""
14 | return 'lazy_tags_{0}'.format(tag_id)
15 |
16 |
17 | def set_lazy_tag_data(tag_id, tag, args=None, kwargs=None):
18 | tag_context = {
19 | 'tag': tag,
20 | 'args': args,
21 | 'kwargs': kwargs,
22 | }
23 |
24 | key = get_cache_key(tag_id)
25 | cache_timeout = getattr(settings, 'LAZY_TAGS_CACHE_TIMEOUT', 60)
26 | cache.set(key, tag_context, cache_timeout)
27 |
28 |
29 | def get_lazy_tag_data(tag_id):
30 | key = get_cache_key(tag_id)
31 | tag_data = cache.get(key)
32 | cache.delete(key)
33 | return tag_data
34 |
35 |
36 | def get_lib_and_tag_name(tag):
37 | """
38 | Takes a tag string and returns the tag library and tag name. For example,
39 | "app_tags.tag_name" is returned as "app_tags", "tag_name" and
40 | "app_tags.sub.tag_name" is returned as "app_tags.sub", "tag_name"
41 | """
42 | if '.' not in tag:
43 | raise ValueError('Tag string must be in the format "tag_lib.tag_name"')
44 | lib = tag.rpartition('.')[0]
45 | tag_name = tag.rpartition('.')[-1]
46 | return lib, tag_name
47 |
48 |
49 | def get_tag_html(tag_id):
50 | """
51 | Returns the Django HTML to load the tag library and render the tag.
52 |
53 | Args:
54 | tag_id (str): The tag id for the to return the HTML for.
55 | """
56 | tag_data = get_lazy_tag_data(tag_id)
57 | tag = tag_data['tag']
58 | args = tag_data['args']
59 | kwargs = tag_data['kwargs']
60 | lib, tag_name = get_lib_and_tag_name(tag)
61 |
62 | args_str = ''
63 | if args:
64 | for arg in args:
65 | if isinstance(arg, six.string_types):
66 | args_str += "'{0}' ".format(arg)
67 | else:
68 | args_str += "{0} ".format(arg)
69 |
70 | kwargs_str = ''
71 | if kwargs:
72 | for name, value in kwargs.items():
73 | if isinstance(value, six.string_types):
74 | kwargs_str += "{0}='{1}' ".format(name, value)
75 | else:
76 | kwargs_str += "{0}={1} ".format(name, value)
77 |
78 | html = '{{% load {lib} %}}{{% {tag_name} {args}{kwargs}%}}'.format(
79 | lib=lib, tag_name=tag_name, args=args_str, kwargs=kwargs_str)
80 |
81 | return html
82 |
--------------------------------------------------------------------------------
/lazy_tags/views.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from django.http import HttpResponse
3 |
4 | from .utils import get_tag_html
5 |
6 |
7 | def tag(request, tag_id=None):
8 | """
9 | The view used to render a tag after the page has loaded.
10 | """
11 | html = get_tag_html(tag_id)
12 | t = template.Template(html)
13 | c = template.RequestContext(request)
14 |
15 | return HttpResponse(t.render(c))
16 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bdist_wheel]
2 | universal=1
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import codecs
2 | import re
3 | import os
4 | from setuptools import setup, find_packages, Command
5 |
6 |
7 | def read(*parts):
8 | filename = os.path.join(os.path.dirname(__file__), *parts)
9 | with codecs.open(filename, encoding='utf-8') as fp:
10 | return fp.read()
11 |
12 |
13 | def find_version(*file_paths):
14 | version_file = read(*file_paths)
15 | version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
16 | version_file, re.M)
17 | if version_match:
18 | return version_match.group(1)
19 | raise RuntimeError("Unable to find version string.")
20 |
21 |
22 | setup(
23 | name='django-lazy-tags',
24 | version=find_version('lazy_tags', '__init__.py'),
25 | description='A Django app for lazy loading template tags over AJAX',
26 | long_description=read('README.rst'),
27 | classifiers=[
28 | 'Development Status :: 4 - Beta',
29 | 'Environment :: Web Environment',
30 | 'Framework :: Django',
31 | 'Framework :: Django :: 1.9',
32 | 'Framework :: Django :: 1.10',
33 | 'Framework :: Django :: 1.11',
34 | 'Framework :: Django :: 2.0',
35 | 'Intended Audience :: Developers',
36 | 'License :: OSI Approved :: MIT License',
37 | 'Operating System :: OS Independent',
38 | 'Programming Language :: Python',
39 | 'Programming Language :: Python :: 2.7',
40 | 'Programming Language :: Python :: 3.4',
41 | 'Programming Language :: Python :: 3.5',
42 | 'Programming Language :: Python :: 3.6',
43 | ],
44 | keywords='ajax, django, templatetag',
45 | author='Grant McConnaughey',
46 | author_email='grantmcconnaughey@gmail.com',
47 | url='https://github.com/grantmcconnaughey/django-lazy-tags/',
48 | license='MIT',
49 | packages=find_packages(exclude=['tests']),
50 | include_package_data=True,
51 | install_requires=[],
52 | )
53 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grantmcconnaughey/django-lazy-tags/c24872c1d9f198abd20669c77380a923092374c2/tests/__init__.py
--------------------------------------------------------------------------------
/tests/models.py:
--------------------------------------------------------------------------------
1 | # Required for compatibility with older versions of Django
2 |
--------------------------------------------------------------------------------
/tests/requirements.txt:
--------------------------------------------------------------------------------
1 | coverage==3.7.1
2 | coveralls
3 | flake8
--------------------------------------------------------------------------------
/tests/settings.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | DATABASE_ENGINE = 'sqlite3'
4 | DEBUG = True
5 |
6 | DATABASES = {
7 | 'default': {
8 | 'ENGINE': 'django.db.backends.sqlite3',
9 | 'NAME': ':memory:',
10 | }
11 | }
12 |
13 | INSTALLED_APPS = [
14 | 'django.contrib.sessions',
15 | 'django.contrib.auth',
16 | 'django.contrib.contenttypes',
17 | 'django.contrib.sites',
18 | 'django.contrib.staticfiles',
19 | 'lazy_tags',
20 | 'tests',
21 | ]
22 |
23 | MIDDLEWARE_CLASSES = (
24 | 'django.middleware.common.CommonMiddleware',
25 | 'django.contrib.sessions.middleware.SessionMiddleware',
26 | 'django.middleware.csrf.CsrfViewMiddleware',
27 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
28 | 'django.contrib.messages.middleware.MessageMiddleware',
29 | )
30 |
31 | ALLOWED_HOSTS = [
32 | 'localhost',
33 | '127.0.0.1',
34 | ]
35 |
36 | PROJECT_ROOT = os.path.dirname(__file__)
37 | ROOT_URLCONF = 'tests.urls'
38 |
39 | SITE_ID = 1
40 |
41 | SECRET_KEY = 'something-something'
42 |
43 | ROOT_URLCONF = 'tests.urls'
44 |
45 | STATIC_URL = '/site_media/static/'
46 | STATIC_ROOT = os.path.join(PROJECT_ROOT, "test_static")
47 |
48 | STATICFILES_FINDERS = (
49 | "django.contrib.staticfiles.finders.FileSystemFinder",
50 | "django.contrib.staticfiles.finders.AppDirectoriesFinder",
51 | )
52 |
53 | # Required in Django>=1.10.
54 | TEMPLATES = [
55 | {
56 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
57 | 'DIRS': [],
58 | 'APP_DIRS': True,
59 | 'OPTIONS': {
60 | # ... some options here ...
61 | },
62 | },
63 | ]
64 |
--------------------------------------------------------------------------------
/tests/templates/tests/_tags.html:
--------------------------------------------------------------------------------
1 | {% load lazy_tags %}
2 | {% load test_tags %}
3 |
4 |