Browse Source

moved shortcuts and template tags refs to markdown

Rafał Pitoń 8 years ago
parent
commit
541b9d2d62
4 changed files with 172 additions and 2 deletions
  1. 2 0
      docs/SUMMARY.md
  2. 59 0
      docs/Shortcuts.md
  3. 110 0
      docs/TemplateTags.md
  4. 1 2
      docs/WritingNewAdminActions.md

+ 2 - 0
docs/SUMMARY.md

@@ -16,6 +16,8 @@
 * [Markup](./Markup.md)
 * [Markup](./Markup.md)
 * [Posting process](./PostingProcess.md)
 * [Posting process](./PostingProcess.md)
 * [Extending pages](./ExtendingPages.md)
 * [Extending pages](./ExtendingPages.md)
+* [Template tags](./TemplateTags.md)
+* [Shortcuts](./Shortcuts.md)
 * [Settings](./settings/README.md)
 * [Settings](./settings/README.md)
   * [Core settings](./settings/Core.md)
   * [Core settings](./settings/Core.md)
   * [Database settings](./settings/Database.md)
   * [Database settings](./settings/Database.md)

+ 59 - 0
docs/Shortcuts.md

@@ -0,0 +1,59 @@
+Shortcut functions
+==================
+
+Just like [Django](https://docs.djangoproject.com/en/{{ book.django_version }}/topics/http/shortcuts/), Misago defines shortcuts module that reduce some procedures to single functions.
+
+This module lives in `misago.views.shortcuts` and in addition to Misago-native shortcut functions, it imports whole of `django.shortcuts`, so you don't have to import it separately in your views.
+
+
+## `paginate(object_list, page, per_page, orphans=0, allow_empty_first_page=True)`
+
+This function is a factory that validates received data and returns [Django's Page](https://docs.djangoproject.com/en/{{ book.django_version }}/topics/pagination/#page-objects) object. In adition it also translates `EmptyPage` errors into `Http404` errors and validates if first page number was explictly defined in url parameter or not.
+
+`paginate` function has certain requirements on handling views that use it. Firstly, views with pagination should have two links instead of one:
+
+```python
+# inside blog.urls.py
+urlpatterns += patterns('blog.views',
+    url(r'^/$', 'index', name='index'),
+    url(r'^/(?P<page>[1-9][0-9]*)/$', 'index', name='index'),
+)
+
+# inside blog.views.py
+def index(request, page=None):
+    # your view that calls paginate()
+```
+
+
+#### Note
+
+Giving `page` argument default value of 1 will make `paginate` function assume that first page was reached via link with explicit first page number and cause redirect loop.
+
+Error handler expects link parameter that contains current page number to be named "page". Otherwise it will fail to create new link and raise `KeyError`.
+
+
+## `validate_slug(model, slug)`
+
+This function compares model instance's "slug" attribute against user-friendly slug that was passed as link parameter. If model's slug attribute is different this function, `misago.views.OutdatedSlug` is raised. This exception is then captured by Misago's exception handler which makes Misago return permanent (http 301) redirect to client with valid link.
+
+Example of view that first fetches object form database and then makes sure user or spider that reaches page has been let known of up-to-date link:
+
+```python
+from misago.views.shortcuts import validate_slug, get_object_or_404
+from myapp.models import Cake
+
+def cake_fans(request, cake_id, cake_slug):
+    # first get cake model from DB
+    cake = get_object_or_404(Cake, pk=cake_id)
+    # issue redirect if cake slug is invalid
+    validate_slug(cake, cacke_slug)
+```
+
+
+#### Notes
+
+You may have noticed that there's no exception handling for either `Http404` exception raised by `get_object_or_404`, nor `OutdatedSlug` exception raised by `validate_slug`. This is by design. Both exceptions are handled by Misago for you so you don't have to spend time writing exception handling boiler plate on every view that fetches objects from database and validates their links.
+
+Naturally if you need to, you can still handle them yourself.
+
+Also, your links should use "slug" parameters only when they are supporting GET requests. For same reason you should call `validate_slug` only when request method is GET or HEAD.

+ 110 - 0
docs/TemplateTags.md

@@ -0,0 +1,110 @@
+Template Tags Reference
+=======================
+
+Misago defines plenty of custom tags and filters for use by template authors.
+
+
+## `misago_batch`
+
+There are situations when you want to slice list of items in template into sublists, e.g. when displaying grid of items in HTML it makes more sense to split iteration into two steps: iteration over rows and items in each row.
+
+`misago_batch` provides two simple and lazy filters that enable you to do this:
+
+
+### `{{ itemslist|batch:4 }}`
+
+Takes one argument, integer individual batch's length, then turns big list into list of lists.
+
+
+```
+{% load misago_batch %}
+
+{% for row in user_profiles|batch:4 %}
+    <div class="row">
+        {% for profile in row %}
+            <div class="col-md-3">
+                {% include "card.html" %}
+            </div>
+        {% endfor %}
+    </div>
+{% endfor %}
+```
+
+
+### `{{ itemslist|batchnonefilled:4 }}`
+
+Works same as `batch` filter, but with one difference:
+
+If last batch length is shorter than requested, it fills it with `None` to make it requested length.
+
+```
+{% load misago_batch %}
+
+{% for row in user_profiles|batchnonefilled:4 %}
+    <div class="row">
+        {% for profile in row %}
+            <div class="col-md-3">
+                {% if profile %}
+                    {% include "card.html" %}
+                {% else %}
+                    &nbsp;
+                {% endif %}
+            </div>
+        {% endfor %}
+    </div>
+{% endfor %}
+```
+
+
+## `misago_capture`
+
+### `{% capture as NAME %}{% endcapture %}`
+
+Captures part of template to variable that may then be displayed many more times.
+
+There is also trimmed flavour `{% capture trimmed as NAME %}{% endcapture %}` that trims captured template part before assinging it to variable.
+
+
+## `misago_dates`
+
+### `{{ item.posted_on|compact_date }}`
+
+Filter that formats date according to format defines in `MISAGO_COMPACT_DATE_FORMAT_DAY_MONTH` setting if date is in current year, or `MISAGO_COMPACT_DATE_FORMAT_DAY_MONTH_YEAR` if not. Defaults to "7 may" for same year dates and "may '13" for past years dates.
+
+
+## `misago_forms`
+
+### `{% form_row form.field labelclass fieldclass%}`
+
+Takes form field as its first argument and renders field complete with label, help and errors. Accept two extra arguments: label class and field class, allowing you to control size of horizontal forms:
+
+```
+{% load misago_forms %}
+
+{% form_row form.somefield %}
+{% form_row form.otherfield 'col-md-3' 'col-md-9' %}
+```
+
+
+### `{% form_input %}`
+
+Takes form field as its only argument and renders it's input.
+
+
+## `misago_json`
+
+### `{{ frontend_context|as_json }}`
+
+Turns value into json string. Perfoms additional escaping on `<` signs so `</script>` are not interpreted as HTML resulting in XSS.
+
+
+## misago_shorthands
+
+### `{{ 'this is outputed'|iftrue:test }}`
+
+Shorthand for simple if clauses: `{{ "fade in"|iftrue:thread.is_closed }}` will render `fade in` in template if `thread.is_closed` evaluates to `True`.
+
+
+### `{{ 'this is outputed'|iffalse:test }}`
+
+Opposite to `iftrue`. Outputs value if test evaluates to `False`.

+ 1 - 2
docs/WritingNewAdminActions.md

@@ -148,8 +148,7 @@ If `kwargs` len is 1, its assumed to be value of seeked model pk value. This mak
 Once model instance is obtained either from database or empty instance is created, this function is called to see intended action is allowed for this request and target. This function is expected to return `None` if no issues are found or string containing error message. If string is returned, its set as error messages, and view interrupts its execution by returning redirect to `root_link`.
 Once model instance is obtained either from database or empty instance is created, this function is called to see intended action is allowed for this request and target. This function is expected to return `None` if no issues are found or string containing error message. If string is returned, its set as error messages, and view interrupts its execution by returning redirect to `root_link`.
 
 
 
 
-.. note::
-   While target argument value is always present, you don't have to do anything with it if its not making any sense for your view.
+While target argument value is always present, you don't have to do anything with it if its not making any sense for your view.
 
 
 
 
 In addition, views are wrapped in database transaction. To turn this behaviour off, define `is_atomic` attribute with value `False`.
 In addition, views are wrapped in database transaction. To turn this behaviour off, define `is_atomic` attribute with value `False`.