prepare 0.9.16; introduced form titles shown in the templates; improved navigation of the form wizards

This commit is contained in:
Artur Barseghyan 2016-11-10 01:44:33 +01:00
parent 8660591e8f
commit 369c2b620f
31 changed files with 257 additions and 42 deletions

View file

@ -15,6 +15,13 @@ are used for versioning (schema follows below):
0.3.4 to 0.4).
- All backwards incompatible changes are mentioned in this document.
0.9.16
------
2016-11-10
- Introduced form titles (shown in view templates).
- Improved navigation of the form wizards.
0.9.15
------
2016-11-07

View file

@ -31,7 +31,6 @@ six==1.10.0
snowballstemmer==1.2.0
Sphinx==1.3.1
sphinx-rtd-theme==0.1.9
sqlparse==0.1.17
traitlets==4.0.0
#Unidecode==0.4.18
virtualenv==13.1.2

View file

@ -10,3 +10,4 @@ django-debug-toolbar==1.5
django-registration-redux>=1.4
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.2.2

View file

@ -11,3 +11,4 @@ django-localeurl>=2.0.2
django-registration-redux==1.2
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -11,3 +11,4 @@ django-localeurl>=2.0.2
django-registration-redux==1.2
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -10,3 +10,4 @@ django-localeurl>=2.0.2
django-registration-redux==1.3
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -11,3 +11,4 @@ django-formtools
django-registration-redux>=1.4
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -3,7 +3,7 @@
Django>=1.9,<1.10
django-admin-tools>=0.7.1
django-autoslug==1.9.3
django-debug-toolbar==0.11.0
django-debug-toolbar==1.5
django-formtools==1.0
django-localeurl==2.0.2
django-nine>=0.1.10
@ -11,3 +11,4 @@ django-nonefield>=0.1
django-registration-redux>=1.4
easy-thumbnails==2.3
vishap>=0.1.5
sqlparse==0.2.2

View file

@ -105,6 +105,11 @@ STATICFILES_FINDERS = (
# Make this unique, and don't share it with anybody.
SECRET_KEY = '97818c*w97Zi8a-m^1coRRrmurMI6+q5_kyn*)s@(*_Pk6q423'
try:
from .local_settings import DEBUG_TEMPLATE
except Exception as err:
DEBUG_TEMPLATE = False
if DJANGO_GTE_1_10:
TEMPLATES = [
{
@ -130,7 +135,7 @@ if DJANGO_GTE_1_10:
'django.template.loaders.eggs.Loader',
'admin_tools.template_loaders.Loader',
],
'debug': DEBUG,
'debug': DEBUG_TEMPLATE,
}
},
]
@ -159,12 +164,12 @@ elif DJANGO_GTE_1_8:
'django.template.loaders.eggs.Loader',
'admin_tools.template_loaders.Loader',
],
'debug': DEBUG,
'debug': DEBUG_TEMPLATE,
}
},
]
else:
TEMPLATE_DEBUG = DEBUG
TEMPLATE_DEBUG = DEBUG_TEMPLATE
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = [

View file

@ -4,6 +4,9 @@ PROJECT_DIR = lambda base : os.path.abspath(os.path.join(os.path.dirname(__file_
DEBUG = True
DEBUG_TOOLBAR = not True
TEMPLATE_DEBUG = not True
DEBUG_TEMPLATE = True
DEV = True
os.environ.setdefault(
'FOBI_SOURCE_PATH',

View file

@ -93,3 +93,5 @@ elif versions.DJANGO_1_10:
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
pass
LOGGING = {}

18
pytest.ini Normal file
View file

@ -0,0 +1,18 @@
[pytest]
norecursedirs=
*.egg
.git
.tox
.env
_sass
build
dist
migrations
python_files =
test_*.py
tests.py
DJANGO_SETTINGS_MODULE=settings.test
addopts=
--cov=fobi
--ignore=.tox
--ignore=requirements

14
runtests.py Normal file
View file

@ -0,0 +1,14 @@
#!/usr/bin/env python
import os
import sys
import pytest
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.test")
sys.path.insert(0, "examples/simple")
return pytest.main()
if __name__ == '__main__':
sys.exit(main())

9
scripts/make_migrations.sh Executable file
View file

@ -0,0 +1,9 @@
echo 'Making messages for django-fobi...'
cd examples/simple/
./manage.py makemigrations fobi
echo 'Making messages for example projects...'
./manage.py makemigrations
echo 'Applying migrations...'
./manage.py migrate

View file

@ -4,7 +4,7 @@ import sys
from distutils.version import LooseVersion
from setuptools import setup, find_packages
version = '0.9.15'
version = '0.9.16'
# ***************************************************************************
# ************************** Django version *********************************

View file

@ -1,6 +1,6 @@
__title__ = 'django-fobi'
__version__ = '0.9.15'
__build__ = 0x000070
__version__ = '0.9.16'
__build__ = 0x000071
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -29,7 +29,7 @@ Installation
4. By default, the submitted form value of `select_multiple`
elements is label (human readable representation of the value chosen).
However, that part of the bahaviour has been made configurable. You can
However, that part of the behaviour has been made configurable. You can
choose between the following options:
Consider the following list of (value, label) choices (the first element in

View file

@ -29,23 +29,23 @@ Installation
4. Ranges are specified within the given min/max values. The default values
are:
.. code-block:: text
.. code-block:: text
- INITIAL: 50
- INITIAL_MAX_VALUE: 100
- INITIAL_MIN_VALUE: 0
- MIN_VALUE: 0
- MAX_VALUE: 100
- STEP: 1
- INITIAL: 50
- INITIAL_MAX_VALUE: 100
- INITIAL_MIN_VALUE: 0
- MIN_VALUE: 0
- MAX_VALUE: 100
- STEP: 1
However, you can override each of them in the settings of your project by
prefixing correspondent names with `FOBI_FORM_ELEMENT_SLIDER_`:
.. code-block:: text
.. code-block:: text
- FOBI_FORM_ELEMENT_SLIDER_INITIAL
- FOBI_FORM_ELEMENT_SLIDER_INITIAL_MAX_VALUE
- FOBI_FORM_ELEMENT_SLIDER_INITIAL_MIN_VALUE
- FOBI_FORM_ELEMENT_SLIDER_MIN_VALUE
- FOBI_FORM_ELEMENT_SLIDER_MAX_VALUE
- FOBI_FORM_ELEMENT_SLIDER_STEP
- FOBI_FORM_ELEMENT_SLIDER_INITIAL
- FOBI_FORM_ELEMENT_SLIDER_INITIAL_MAX_VALUE
- FOBI_FORM_ELEMENT_SLIDER_INITIAL_MIN_VALUE
- FOBI_FORM_ELEMENT_SLIDER_MIN_VALUE
- FOBI_FORM_ELEMENT_SLIDER_MAX_VALUE
- FOBI_FORM_ELEMENT_SLIDER_STEP

View file

@ -1,5 +1,5 @@
{% extends "fobi/generic/snippets/form_wizard_ajax.html" %}
{% load i18n %}
{% block form_page_header_html_class %}page-header{% endblock %}
{% block form_html_class %}form-horizontal{% endblock %}
@ -9,3 +9,43 @@
{% block form_button_wrapper_html_class %}controls{% endblock %}
{% block form_primary_button_html_class %}btn btn-primary{% endblock %}
{% block form_wizard_previous_button_html_class %}btn btn-primary{% endblock %}
{% block form_wizard_first_button_html_class %}btn btn-primary{% endblock %}
{% block form_wizard_first_button_text %}{% trans "First" %}{% endblock %}
{% block form_primary_button_text %}{% trans "Next" %}{% endblock %}
{% block form_wizard_previous_button_text %}{% trans "Previous" %}{% endblock %}
{% block form_page_sub_title_wrapper %}
<nav aria-label="...">
<ul class="pagination">
<li class="disabled">
<span>
<span aria-hidden="true">&laquo;</span>
</span>
</li>
{% for step_index in steps_range %}
{% if step_index == wizard.steps.step1 %}
<li class="active">
<span>{{ step_index }} <span class="sr-only">{% trans "(current)" %}</span></span>
</li>
{% else %}
<li class="disabled">
<span>
<span aria-hidden="true">{{ step_index }}</span>
</span>
</li>
{% endif %}
{% endfor %}
<li class="disabled">
<span>
<span aria-hidden="true">&raquo;</span>
</span>
</li>
</ul>
</nav>
{% endblock form_page_sub_title_wrapper %}

View file

@ -70,7 +70,7 @@ class FormEntryForm(forms.ModelForm):
"""Meta class."""
model = FormEntry
fields = ('name', 'is_public', 'success_page_title',
fields = ('name', 'title', 'is_public', 'success_page_title',
'success_page_message', 'action',) # 'is_cloneable',
def __init__(self, *args, **kwargs):
@ -89,6 +89,10 @@ class FormEntryForm(forms.ModelForm):
attrs={'class': theme.form_element_html_class}
)
self.fields['title'].widget = forms.widgets.TextInput(
attrs={'class': theme.form_element_html_class}
)
self.fields['success_page_title'].widget = forms.widgets.TextInput(
attrs={'class': theme.form_element_html_class}
)
@ -315,8 +319,8 @@ class FormWizardEntryForm(forms.ModelForm):
"""Meta class."""
model = FormWizardEntry
fields = ('name', 'is_public', 'success_page_title',
'success_page_message',)
fields = ('name', 'title', 'is_public', 'success_page_title',
'success_page_message', 'show_all_navigation_buttons',)
# 'wizard_type'
# 'action',
# 'is_cloneable',
@ -337,6 +341,15 @@ class FormWizardEntryForm(forms.ModelForm):
attrs={'class': theme.form_element_html_class}
)
self.fields['title'].widget = forms.widgets.TextInput(
attrs={'class': theme.form_element_html_class}
)
self.fields['show_all_navigation_buttons'].widget = \
forms.widgets.CheckboxInput(
attrs={'data-customforms': 'disabled'}
)
self.fields['success_page_title'].widget = forms.widgets.TextInput(
attrs={'class': theme.form_element_html_class}
)

View file

@ -209,12 +209,16 @@ class IntegrationProcessor(object):
theme = get_theme(request=request, as_instance=True)
theme.collect_plugin_media(form_element_entries)
form_title = instance.form_title \
if instance.form_title \
else instance.form_entry.title
context = self.get_context_data(
request=request,
instance=instance,
form=form,
fobi_theme=theme,
fobi_form_title=instance.form_title,
fobi_form_title=form_title,
fobi_hide_form_title=instance.hide_form_title,
fobi_form_submit_button_text=instance.form_submit_button_text
)

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.11 on 2016-11-08 21:53
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('fobi', '0010_formwizardhandler'),
]
operations = [
migrations.AddField(
model_name='formentry',
name='title',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Title'),
),
]

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.11 on 2016-11-09 21:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('fobi', '0011_formentry_title'),
]
operations = [
migrations.AddField(
model_name='formwizardentry',
name='title',
field=models.CharField(blank=True, help_text='Shown in templates ifavailable.', max_length=255, null=True, verbose_name='Title'),
),
migrations.AlterField(
model_name='formentry',
name='title',
field=models.CharField(blank=True, help_text='Shown in templates ifavailable.', max_length=255, null=True, verbose_name='Title'),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-11-09 23:40
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('fobi', '0012_auto_20161109_1550'),
]
operations = [
migrations.AddField(
model_name='formwizardentry',
name='show_all_navigation_buttons',
field=models.BooleanField(default=False, help_text='Show all navigation buttons.', verbose_name='Show all navigation buttons?'),
),
]

View file

@ -256,6 +256,9 @@ class FormWizardEntry(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, verbose_name=_("User"))
name = models.CharField(_("Name"), max_length=255)
title = models.CharField(_("Title"), max_length=255, null=True,
blank=True, help_text=_("Shown in templates if"
"available."))
slug = AutoSlugField(populate_from='name', verbose_name=_("Slug"),
unique=True)
is_public = models.BooleanField(
@ -276,6 +279,10 @@ class FormWizardEntry(models.Model):
help_text=_("Custom message text to display after valid form is "
"submitted")
)
show_all_navigation_buttons = models.BooleanField(
_("Show all navigation buttons?"), default=False,
help_text=_("Show all navigation buttons.")
)
# action = models.CharField(
# _("Action"), max_length=255, null=True, blank=True,
# help_text=_("Custom form action; don't fill this field, unless "
@ -319,20 +326,20 @@ class FormEntry(models.Model):
:Properties:
- `user` (django.contrib.auth.models.User: User owning the plugin.
- `wizard` (str): Form wizard to which the form entry belongs to.
- `name` (str): Form name.
- `title` (str): Form title - used in templates.
- `slug` (str): Form slug.
- `description` (str): Form description.
- `is_public` (bool): If set to True, is visible to public.
- `is_cloneable` (bool): If set to True, is cloneable.
- `position` (int): Ordering position in the wizard.
"""
# form_wizard_entry = models.ForeignKey(
# FormWizardEntry, verbose_name=_("Form wizard"), null=True, blank=True
# )
user = models.ForeignKey(AUTH_USER_MODEL, verbose_name=_("User"))
name = models.CharField(_("Name"), max_length=255)
title = models.CharField(_("Title"), max_length=255, null=True,
blank=True, help_text=_("Shown in templates if"
"available."))
slug = AutoSlugField(
populate_from='name', verbose_name=_("Slug"), unique=True
)

View file

@ -1,6 +1,7 @@
{% block form_page_header_wrapper %}
<div class="{% block form_page_header_html_class %}{% endblock %}">
{% block form_page_title_wrapper %}<h1>{% block form_page_title %}{% endblock %}</h1>{% endblock form_page_title_wrapper %}
{% block form_page_sub_title_wrapper %}{% endblock form_page_sub_title_wrapper %}
</div>
{% endblock form_page_header_wrapper %}
@ -14,7 +15,11 @@
<div class="{% block form_button_outer_wrapper_html_class %}{% endblock %}">
<div class="{% block form_button_wrapper_html_class %}{% endblock %}">
{% block form_buttons %}
<button type="submit" class="{% block form_primary_button_html_class %}{% endblock %}">{% block form_primary_button_text %}{% endblock %}</button>
{% if form_wizard_entry.show_all_navigation_buttons %}
{% block form_wizard_first_button_wrapper %}<button type="submit" name="wizard_goto_step" value="{{ wizard.steps.first }}" class="{% block form_wizard_first_button_html_class %}{% endblock %}">{% block form_wizard_first_button_text %}{% endblock %}</button>{% endblock form_wizard_first_button_wrapper %}
{% block form_wizard_previous_button_wrapper %}<button type="submit" name="wizard_goto_step" value="{{ wizard.steps.prev }}" class="{% block form_wizard_previous_button_html_class %}{% endblock %}">{% block form_wizard_previous_button_text %}{% endblock %}</button>{% endblock form_wizard_previous_button_wrapper %}
{% endif %}
{% block form_wizard_next_button_wrapper %}<button type="submit" name="submit" class="{% block form_primary_button_html_class %}{% endblock %}">{% block form_primary_button_text %}{% endblock %}</button>{% endblock form_wizard_next_button_wrapper %}
{% endblock form_buttons %}
</div>
</div>

View file

@ -1,6 +1,7 @@
{% block form_page_header_wrapper %}
<div class="{% block form_page_header_html_class %}{% endblock %}">
{% block form_page_title_wrapper %}<h1>{% block form_page_title %}{% endblock form_page_title %}</h1>{% endblock form_page_title_wrapper %}
{% block form_page_sub_title_wrapper %}<strong>{% block form_page_sub_title %}{% endblock form_page_sub_title %}</strong>{% endblock form_page_sub_title_wrapper %}
</div>
{% endblock form_page_header_wrapper %}

View file

@ -2,7 +2,7 @@
{% load i18n %}
{% block page-title %}{% trans "View form" %}{% endblock page-title %}
{% block page-title %}{% if form_entry.title %}{{ form_entry.title }}{% else %}{% trans "View form" %}{% endif %}{% endblock page-title %}
{% block navbar-menu-content %}
<li><a href="{% url 'fobi.edit_form_entry' form_entry.pk %}">{% trans "Edit" %}</a></li>

View file

@ -2,7 +2,7 @@
{% load i18n %}
{% block page-title %}{% trans "View form wizard" %}{% endblock page-title %}
{% block page-title %}{% if fobi_form_wizard_title %}{{ fobi_form_wizard_title }}{% else %}{% trans "View form wizard" %}{% endif %}{% endblock page-title %}
{% block dashboard-menu-item %}
<a class="navbar-brand" href="{% url 'fobi.form_wizards_dashboard' %}">{{ fobi_theme.project_name }}</a>

View file

@ -6,7 +6,7 @@
{% if fobi_form_title %}{{ fobi_form_title }}{% else %}{% trans "View form" %}{% endif %}
{% endblock form_page_title %}
{% block form_primary_button_text %}{% if fobi_form_submit_button_text %}{{ fobi_form_submit_button_text }}{% else %}{% trans "Submit" %}{% endif %}{% endblock %}
{% block form_primary_button_text %}{% if fobi_form_submit_button_text %}{{ fobi_form_submit_button_text }}{% else %}{% trans "Next" %}{% endif %}{% endblock %}
{% block form_buttons %}
{{ block.super }}
{% endblock form_buttons %}

View file

@ -1407,15 +1407,23 @@ class FormWizardView(DynamicSessionWizardView):
context_data = super(FormWizardView, self).get_context_data(
form=form, **kwargs
)
form_entry = self.get_form_entry_for_step(self.steps.step0)
context_data.update({
'form_wizard_entry': self.form_wizard_entry,
'form_wizard_mode': True,
'fobi_theme': self.fobi_theme,
'fobi_form_title': form_entry.title,
'fobi_form_wizard_title': self.form_wizard_entry.title,
'steps_range': range(self.steps.step1, self.steps.count+1)
})
return context_data
def get_form_entry_for_step(self, step):
"""Get form entry title for step."""
form_slug = self.form_list[self.steps.step0][0]
return self.form_entry_mapping[form_slug]
def get_initial_wizard_data(self, request, *args, **kwargs):
"""Get initial wizard data."""
try:
@ -1511,8 +1519,12 @@ class FormWizardView(DynamicSessionWizardView):
# Get current form entry
form_entry = self.form_entry_mapping[self.steps.current]
# Fire plugin processors
form = submit_plugin_form_data(form_entry=form_entry,
request=self.request, form=form)
form = submit_plugin_form_data(
form_entry=form_entry,
request=self.request,
form=form,
# **{'': ''} # TODO
)
# Form wizards make use of form.data instead of form.cleaned_data.
# Therefore, we update the form.data with values from
# form.cleaned_data.
@ -1582,7 +1594,8 @@ class FormWizardView(DynamicSessionWizardView):
form_obj = submit_plugin_form_data(
form_entry=form_entry,
request=self.request,
form=form_obj
form=form_obj,
# **{'': ''} # TODO
)
final_forms[form_key] = form_obj
@ -2123,8 +2136,11 @@ def view_form_entry(request, form_entry_slug, theme=None, template_name=None):
)
# Fire plugin processors
form = submit_plugin_form_data(form_entry=form_entry,
request=request, form=form)
form = submit_plugin_form_data(
form_entry=form_entry,
request=request,
form=form
)
# Fire form valid callbacks
form = fire_form_callbacks(form_entry=form_entry,
@ -2194,6 +2210,7 @@ def view_form_entry(request, form_entry_slug, theme=None, template_name=None):
'form': form,
'form_entry': form_entry,
'fobi_theme': theme,
'fobi_form_title': form_entry.title,
}
if not template_name: