diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c47e741f3..454d20f37 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,23 @@ Release history ===================================== +0.1.6 +------------------------------------- +2014-10-25 + +- Minor improvements in the theming API. From now on the + ``view_embed_form_entry_ajax_template`` template would be used + when integrating the form rendering from other products (for example, + a CMS page, which has a widget which references the form object. If + that property is left empty, the ``view_form_entry_ajax_template`` + is used. For a success page the ``embed_form_entry_submitted_ajax_template`` + template would be used. +- Functional improvements of the FeinCMS integration (the widget). If you + have used the FeinCMS widget of earlier versions, you likely want to update + to this one. From now on you can select a custom form title and the button + text, as well as provide custom success page title and the success message; + additionally, it has been made possible to hide the form- or success-page- + titles. + 0.1.5 ------------------------------------- 2014-10-23 diff --git a/examples/README.rst b/examples/README.rst index 17ac5901f..847507dae 100644 --- a/examples/README.rst +++ b/examples/README.rst @@ -63,3 +63,20 @@ Django admin interface: - URL: http://127.0.0.1:8001/admin/ - Admin username: test_admin - Admin password: test + +Various setups +============================================ +There are number of setups included (names are self-explanatory): + +- Bootstrap3 theme + Captcha (runserver-bootstrap3-theme-captcha) :8000 +- Bootstrap3 theme + Django 1.7 + Captcha (runserver-bootstrap3-theme-django17-captcha) :8000 +- Bootstrap3 theme + Django 1.7 (runserver-bootstrap3-theme-django17) :8000 +- Bootstrap3 theme + FeinCMS integration (runserver-bootstrap3-theme-feincms-integration) :8000 +- Bootstrap3 theme (runserver-bootstrap3-theme) :8000 + +- Foundation 5 theme + FeinCMS integration (runserver-foundation5-theme-feincms-integration) :8001 +- Foundation 5 theme :8001 + +- Override of the simple theme (runserver-override-simple-theme) :8003 + +- Simple theme (runserver-simple-theme) :8002 diff --git a/examples/requirements.txt b/examples/requirements.txt index ac12ce2a9..7a03b6150 100644 --- a/examples/requirements.txt +++ b/examples/requirements.txt @@ -1,5 +1,5 @@ -#Django>=1.5,<1.7 Django>=1.5,<1.8 +FeinCMS>=1.9,<1.10 Jinja2 MarkupSafe South diff --git a/examples/simple/page/migrations/0004_auto__add_field_fobiformwidget_form_template_name__add_field_fobiformw.py b/examples/simple/page/migrations/0004_auto__add_field_fobiformwidget_form_template_name__add_field_fobiformw.py new file mode 100644 index 000000000..55d808f4f --- /dev/null +++ b/examples/simple/page/migrations/0004_auto__add_field_fobiformwidget_form_template_name__add_field_fobiformw.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'FobiFormWidget.form_template_name' + db.add_column(u'page_page_fobiformwidget', 'form_template_name', + self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), + keep_default=False) + + # Adding field 'FobiFormWidget.hide_form_title' + db.add_column(u'page_page_fobiformwidget', 'hide_form_title', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + # Adding field 'FobiFormWidget.form_title' + db.add_column(u'page_page_fobiformwidget', 'form_title', + self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), + keep_default=False) + + # Adding field 'FobiFormWidget.form_submit_button_text' + db.add_column(u'page_page_fobiformwidget', 'form_submit_button_text', + self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), + keep_default=False) + + # Adding field 'FobiFormWidget.success_page_template_name' + db.add_column(u'page_page_fobiformwidget', 'success_page_template_name', + self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), + keep_default=False) + + # Adding field 'FobiFormWidget.hide_success_page_title' + db.add_column(u'page_page_fobiformwidget', 'hide_success_page_title', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + # Adding field 'FobiFormWidget.success_page_title' + db.add_column(u'page_page_fobiformwidget', 'success_page_title', + self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), + keep_default=False) + + # Adding field 'FobiFormWidget.success_page_text' + db.add_column(u'page_page_fobiformwidget', 'success_page_text', + self.gf('django.db.models.fields.TextField')(null=True, blank=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'FobiFormWidget.form_template_name' + db.delete_column(u'page_page_fobiformwidget', 'form_template_name') + + # Deleting field 'FobiFormWidget.hide_form_title' + db.delete_column(u'page_page_fobiformwidget', 'hide_form_title') + + # Deleting field 'FobiFormWidget.form_title' + db.delete_column(u'page_page_fobiformwidget', 'form_title') + + # Deleting field 'FobiFormWidget.form_submit_button_text' + db.delete_column(u'page_page_fobiformwidget', 'form_submit_button_text') + + # Deleting field 'FobiFormWidget.success_page_template_name' + db.delete_column(u'page_page_fobiformwidget', 'success_page_template_name') + + # Deleting field 'FobiFormWidget.hide_success_page_title' + db.delete_column(u'page_page_fobiformwidget', 'hide_success_page_title') + + # Deleting field 'FobiFormWidget.success_page_title' + db.delete_column(u'page_page_fobiformwidget', 'success_page_title') + + # Deleting field 'FobiFormWidget.success_page_text' + db.delete_column(u'page_page_fobiformwidget', 'success_page_text') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'fobi.formentry': { + 'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormEntry'}, + 'action': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'form_wizard_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormWizardEntry']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'position': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}), + 'success_page_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'success_page_title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'fobi.formwizardentry': { + 'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormWizardEntry'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'page.fobiformwidget': { + 'Meta': {'ordering': "['ordering']", 'object_name': 'FobiFormWidget', 'db_table': "u'page_page_fobiformwidget'"}, + 'form_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormEntry']"}), + 'form_submit_button_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'form_template_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'form_title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'hide_form_title': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'hide_success_page_title': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'fobiformwidget_set'", 'to': u"orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'success_page_template_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'success_page_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'success_page_title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}) + }, + u'page.page': { + 'Meta': {'ordering': "['tree_id', 'lft']", 'object_name': 'Page'}, + '_cached_url': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'db_index': 'True', 'blank': 'True'}), + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'override_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': u"orm['page.Page']"}), + 'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150'}), + 'template_key': ('django.db.models.fields.CharField', [], {'default': "'page_base'", 'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'translation_of': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'translations'", 'null': 'True', 'to': u"orm['page.Page']"}), + u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) + }, + u'page.rawcontent': { + 'Meta': {'ordering': "['ordering']", 'object_name': 'RawContent', 'db_table': "u'page_page_rawcontent'"}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rawcontent_set'", 'to': u"orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + u'page.richtextcontent': { + 'Meta': {'ordering': "['ordering']", 'object_name': 'RichTextContent', 'db_table': "u'page_page_richtextcontent'"}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'richtextcontent_set'", 'to': u"orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'text': ('feincms.contrib.richtext.RichTextField', [], {'blank': 'True'}) + } + } + + complete_apps = ['page'] \ No newline at end of file diff --git a/examples/simple/runserver-bootstrap3-theme-captcha.sh b/examples/simple/runserver-bootstrap3-theme-captcha.sh index 90daecf02..b46e0630b 100755 --- a/examples/simple/runserver-bootstrap3-theme-captcha.sh +++ b/examples/simple/runserver-bootstrap3-theme-captcha.sh @@ -1,2 +1,2 @@ #workon fobi -./manage.py runserver 0.0.0.0:8004 --settings=settings_bootstrap3_theme_captcha --traceback -v 3 +./manage.py runserver 0.0.0.0:8000 --settings=settings_bootstrap3_theme_captcha --traceback -v 3 diff --git a/examples/simple/runserver-bootstrap3-theme-django17-captcha.sh b/examples/simple/runserver-bootstrap3-theme-django17-captcha.sh index 48df27388..8f398f696 100755 --- a/examples/simple/runserver-bootstrap3-theme-django17-captcha.sh +++ b/examples/simple/runserver-bootstrap3-theme-django17-captcha.sh @@ -1,2 +1,2 @@ #workon fobi -./manage.py runserver 0.0.0.0:8006 --traceback -v 3 --settings=settings_bootstrap3_theme_django17_captcha --traceback -v 3 +./manage.py runserver 0.0.0.0:8000 --traceback -v 3 --settings=settings_bootstrap3_theme_django17_captcha --traceback -v 3 diff --git a/examples/simple/runserver-bootstrap3-theme-django17.sh b/examples/simple/runserver-bootstrap3-theme-django17.sh index 4fc0ad1df..fcf348caf 100755 --- a/examples/simple/runserver-bootstrap3-theme-django17.sh +++ b/examples/simple/runserver-bootstrap3-theme-django17.sh @@ -1,2 +1,2 @@ #workon fobi -./manage.py runserver 0.0.0.0:8006 --traceback -v 3 --settings=settings_bootstrap3_theme_django17 --traceback -v 3 +./manage.py runserver 0.0.0.0:8000 --traceback -v 3 --settings=settings_bootstrap3_theme_django17 --traceback -v 3 diff --git a/examples/simple/runserver-bootstrap3-theme-feincms-integration.sh b/examples/simple/runserver-bootstrap3-theme-feincms-integration.sh new file mode 100755 index 000000000..20a918867 --- /dev/null +++ b/examples/simple/runserver-bootstrap3-theme-feincms-integration.sh @@ -0,0 +1,2 @@ +#workon fobi +./manage.py runserver 0.0.0.0:8000 --settings=settings_bootstrap3_theme_feincms --traceback -v 3 diff --git a/examples/simple/runserver-feincms-integration.sh b/examples/simple/runserver-feincms-integration.sh deleted file mode 100755 index 72e757694..000000000 --- a/examples/simple/runserver-feincms-integration.sh +++ /dev/null @@ -1,2 +0,0 @@ -#workon fobi -./manage.py runserver 0.0.0.0:8005 --settings=settings_feincms --traceback -v 3 diff --git a/examples/simple/runserver-foundation5-theme-feincms-integration.sh b/examples/simple/runserver-foundation5-theme-feincms-integration.sh new file mode 100755 index 000000000..dacc452bd --- /dev/null +++ b/examples/simple/runserver-foundation5-theme-feincms-integration.sh @@ -0,0 +1,3 @@ +#workon fobi +#./manage.py collectstatic --noinput --settings=settings_foundation5_theme_feincms --traceback -v 3 +./manage.py runserver 0.0.0.0:8001 --settings=settings_foundation5_theme_feincms --traceback -v 3 diff --git a/examples/simple/settings.py b/examples/simple/settings.py index 8e520ffca..7882f5ba7 100644 --- a/examples/simple/settings.py +++ b/examples/simple/settings.py @@ -160,7 +160,7 @@ # Third party apps used in the project 'south', # Database migration app - #'tinymce', # TinyMCE + 'tinymce', # TinyMCE 'easy_thumbnails', # Thumbnailer 'registration', # Auth views and registration app #'localeurl', # Locale URL @@ -237,6 +237,20 @@ 'form_button_wrapper_html_class': 'controls', 'form_button_html_class': 'btn', 'form_primary_button_html_class': 'btn-primary pull-right', + 'feincms_integration': { + 'form_template_choices': [ + ( + 'fobi/bootstrap3_extras/view_embed_form_entry_ajax.html', + gettext("Custom bootstrap3 embed form view template") + ), + ], + 'success_page_template_choices': [ + ( + 'fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html', + gettext("Custom bootstrap3 embed form entry submitted template") + ), + ], + }, }, 'foundation5': { 'page_header_html_class': '', @@ -245,6 +259,20 @@ 'form_button_wrapper_html_class': 'controls', 'form_button_html_class': 'radius button', 'form_primary_button_html_class': 'btn-primary', + 'feincms_integration': { + 'form_template_choices': [ + ( + 'fobi/foundation5_extras/view_embed_form_entry_ajax.html', + gettext("Custom foundation5 embed form view template") + ), + ], + 'success_page_template_choices': [ + ( + 'fobi/foundation5_extras/embed_form_entry_submitted_ajax.html', + gettext("Custom foundation5 embed form entry submitted template") + ), + ], + }, }, 'simple': { 'page_header_html_class': '', @@ -253,6 +281,8 @@ 'form_button_wrapper_html_class': 'submit-row', 'form_button_html_class': 'btn', 'form_primary_button_html_class': 'btn-primary', + 'feincms_integration': { + }, } } diff --git a/examples/simple/settings_bootstrap3_theme_django17.py b/examples/simple/settings_bootstrap3_theme_django17.py index 815988a8d..1f12e58f6 100644 --- a/examples/simple/settings_bootstrap3_theme_django17.py +++ b/examples/simple/settings_bootstrap3_theme_django17.py @@ -3,6 +3,7 @@ INSTALLED_APPS = list(INSTALLED_APPS) try: - INSTALLED_APPS.remove('south') + INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None + INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None except Exception as e: pass diff --git a/examples/simple/settings_bootstrap3_theme_django17_captcha.py b/examples/simple/settings_bootstrap3_theme_django17_captcha.py index 1bd78d1b4..d0a1e3bf2 100755 --- a/examples/simple/settings_bootstrap3_theme_django17_captcha.py +++ b/examples/simple/settings_bootstrap3_theme_django17_captcha.py @@ -3,7 +3,8 @@ INSTALLED_APPS = list(INSTALLED_APPS) try: - INSTALLED_APPS.remove('south') + INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None + INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None INSTALLED_APPS.append('captcha') INSTALLED_APPS.append('fobi.contrib.plugins.form_elements.fields.captcha') except Exception as e: diff --git a/examples/simple/settings_feincms.py b/examples/simple/settings_bootstrap3_theme_feincms.py similarity index 100% rename from examples/simple/settings_feincms.py rename to examples/simple/settings_bootstrap3_theme_feincms.py diff --git a/examples/simple/settings_foundation5_theme_feincms.py b/examples/simple/settings_foundation5_theme_feincms.py new file mode 100644 index 000000000..98b26f173 --- /dev/null +++ b/examples/simple/settings_foundation5_theme_feincms.py @@ -0,0 +1,16 @@ +from settings import * + +INSTALLED_APPS = list(INSTALLED_APPS) +INSTALLED_APPS += [ + 'feincms', # FeinCMS + + 'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app + + 'page', # Example +] + +FEINCMS_RICHTEXT_INIT_CONTEXT = { + 'TINYMCE_JS_URL': STATIC_URL + 'tiny_mce/tiny_mce.js', +} + +FOBI_DEFAULT_THEME = 'foundation5' diff --git a/examples/simple/templates/fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html b/examples/simple/templates/fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html new file mode 100644 index 000000000..846678efb --- /dev/null +++ b/examples/simple/templates/fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html @@ -0,0 +1,11 @@ +{% extends fobi_theme.embed_form_entry_submitted_ajax_template %} + +{% load i18n %} + +{% block form_page_header_wrapper %} + + {{ block.super }} +{% endblock %} diff --git a/examples/simple/templates/fobi/bootstrap3_extras/view_embed_form_entry_ajax.html b/examples/simple/templates/fobi/bootstrap3_extras/view_embed_form_entry_ajax.html new file mode 100644 index 000000000..21031532c --- /dev/null +++ b/examples/simple/templates/fobi/bootstrap3_extras/view_embed_form_entry_ajax.html @@ -0,0 +1,11 @@ +{% extends fobi_theme.view_embed_form_entry_ajax_template %} + +{% load i18n %} + +{% block form_page_header_wrapper %} + + {{ block.super }} +{% endblock %} diff --git a/examples/simple/templates/fobi/foundation5_extras/embed_form_entry_submitted_ajax.html b/examples/simple/templates/fobi/foundation5_extras/embed_form_entry_submitted_ajax.html new file mode 100644 index 000000000..846678efb --- /dev/null +++ b/examples/simple/templates/fobi/foundation5_extras/embed_form_entry_submitted_ajax.html @@ -0,0 +1,11 @@ +{% extends fobi_theme.embed_form_entry_submitted_ajax_template %} + +{% load i18n %} + +{% block form_page_header_wrapper %} + + {{ block.super }} +{% endblock %} diff --git a/examples/simple/templates/fobi/foundation5_extras/view_embed_form_entry_ajax.html b/examples/simple/templates/fobi/foundation5_extras/view_embed_form_entry_ajax.html new file mode 100644 index 000000000..21031532c --- /dev/null +++ b/examples/simple/templates/fobi/foundation5_extras/view_embed_form_entry_ajax.html @@ -0,0 +1,11 @@ +{% extends fobi_theme.view_embed_form_entry_ajax_template %} + +{% load i18n %} + +{% block form_page_header_wrapper %} + + {{ block.super }} +{% endblock %} diff --git a/examples/simple/urls.py b/examples/simple/urls.py index e02a93a3c..6ca166e17 100644 --- a/examples/simple/urls.py +++ b/examples/simple/urls.py @@ -63,7 +63,7 @@ from page.models import Page Page urlpatterns += patterns('', - url(r'', include('feincms.urls')), + url(r'^pages/', include('feincms.urls')), ) # Conditionally including Captcha URls in case if diff --git a/install_feincms.sh b/install_feincms.sh new file mode 100755 index 000000000..2a7dfad38 --- /dev/null +++ b/install_feincms.sh @@ -0,0 +1,9 @@ +#pip install -r examples/requirements.txt --allow-all-external --allow-unverified django-admin-tools +pip install -r examples/requirements.txt +python setup.py install +mkdir -p examples/logs examples/db examples/media examples/media/static examples/media/fobi_plugins/content_image +mkdir -p examples/media/fobi_plugins/file +python examples/simple/manage.py collectstatic --noinput --settings=settings_foundation5_theme_feincms --traceback -v 3 +python examples/simple/manage.py syncdb --noinput --settings=settings_foundation5_theme_feincms --traceback -v 3 +python examples/simple/manage.py migrate --noinput --settings=settings_foundation5_theme_feincms --traceback -v 3 +python examples/simple/manage.py fobi_create_test_data --settings=settings_foundation5_theme_feincms --traceback -v 3 diff --git a/reinstall_feincms.sh b/reinstall_feincms.sh new file mode 100755 index 000000000..6021087d0 --- /dev/null +++ b/reinstall_feincms.sh @@ -0,0 +1,3 @@ +reset +./uninstall.sh +./install_feincms.sh \ No newline at end of file diff --git a/setup.py b/setup.py index bc32ae00a..b915ad844 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ for locale_dir in locale_dirs: locale_files += [os.path.join(locale_dir, f) for f in os.listdir(locale_dir)] -version = '0.1.5' +version = '0.1.6' install_requires = [ 'Pillow>=2.0.0', diff --git a/src/fobi/__init__.py b/src/fobi/__init__.py index d64d4fd79..0a916425c 100644 --- a/src/fobi/__init__.py +++ b/src/fobi/__init__.py @@ -1,6 +1,6 @@ __title__ = 'django-fobi' -__version__ = '0.1.5' -__build__ = 0x000006 +__version__ = '0.1.6' +__build__ = 0x000007 __author__ = 'Artur Barseghyan ' __copyright__ = 'Copyright (c) 2014 Artur Barseghyan' __license__ = 'GPL 2.0/LGPL 2.1' diff --git a/src/fobi/base.py b/src/fobi/base.py index 18f18b777..37b893574 100644 --- a/src/fobi/base.py +++ b/src/fobi/base.py @@ -76,6 +76,15 @@ class BaseTheme(object): """ Base theme. + + :property str view_embed_form_entry_ajax_template: A template to be used + when integrating the form rendering from other products (for example, + a CMS page, which has a widget which references the form object. If + that property is left empty, the ``view_form_entry_ajax_template`` + is used. + :property str embed_form_entry_submitted_ajax_template: A template to be + used when integrating into other products (CMS page). Serves the + thank you. """ uid = None name = None @@ -144,8 +153,10 @@ class BaseTheme(object): edit_form_handler_entry_ajax_template = 'fobi/generic/edit_form_handler_entry_ajax.html' form_entry_submitted_template = 'fobi/generic/form_entry_submitted.html' form_entry_submitted_ajax_template = 'fobi/generic/form_entry_submitted_ajax.html' + embed_form_entry_submitted_ajax_template = None view_form_entry_template = 'fobi/generic/view_form_entry.html' view_form_entry_ajax_template = 'fobi/generic/view_form_entry_ajax.html' + view_embed_form_entry_ajax_template = None # ************************************************************************* # ******************** Extras that make things easy *********************** @@ -214,6 +225,15 @@ def __init__(self, user=None): if not self.form_edit_ajax: self.form_edit_ajax = self.form_ajax + # If no specific ``view_embed_form_entry_ajax_template`` specified, fall + # back to the ``view_form_entry_ajax_template``. + if not self.view_embed_form_entry_ajax_template: + self.view_embed_form_entry_ajax_template = self.view_form_entry_ajax_template + + # Some sort of a embed thank you. + if not self.embed_form_entry_submitted_ajax_template: + self.embed_form_entry_submitted_ajax_template = self.form_entry_submitted_ajax_template + # Set theme specific data from settings for to be # refered like `fobi_theme.custom_data`. self.custom_data = self.get_custom_data() diff --git a/src/fobi/contrib/apps/feincms_integration/README.rst b/src/fobi/contrib/apps/feincms_integration/README.rst index 5763f9ca6..dcd493d78 100644 --- a/src/fobi/contrib/apps/feincms_integration/README.rst +++ b/src/fobi/contrib/apps/feincms_integration/README.rst @@ -67,3 +67,8 @@ your_project/admin.py from page.models import Page admin.site.register(Page, PageAdmin) + +Usage +=============================================== +Note, that rendering of the FeinCMS widget happens with help +theme template ``view_form_entry_ajax_template``. diff --git a/src/fobi/contrib/apps/feincms_integration/defaults.py b/src/fobi/contrib/apps/feincms_integration/defaults.py index 78eaab5fd..627d002b7 100644 --- a/src/fobi/contrib/apps/feincms_integration/defaults.py +++ b/src/fobi/contrib/apps/feincms_integration/defaults.py @@ -2,6 +2,13 @@ __author__ = 'Artur Barseghyan ' __copyright__ = 'Copyright (c) 2014 Artur Barseghyan' __license__ = 'GPL 2.0/LGPL 2.1' -__all__ = ('WIDGET_FORM_SENT_GET_PARAM',) +__all__ = ( + 'WIDGET_FORM_SENT_GET_PARAM', 'FORM_TEMPLATE_CHOICES', + 'SUCCESS_PAGE_TEMPLATE_CHOICES', +) WIDGET_FORM_SENT_GET_PARAM = 'sent' + +FORM_TEMPLATE_CHOICES = [] + +SUCCESS_PAGE_TEMPLATE_CHOICES = [] diff --git a/src/fobi/contrib/apps/feincms_integration/helpers.py b/src/fobi/contrib/apps/feincms_integration/helpers.py new file mode 100644 index 000000000..70800df60 --- /dev/null +++ b/src/fobi/contrib/apps/feincms_integration/helpers.py @@ -0,0 +1,56 @@ +__title__ = 'fobi.contrib.apps.feincms_integration.helpers' +__author__ = 'Artur Barseghyan ' +__copyright__ = 'Copyright (c) 2014 Artur Barseghyan' +__license__ = 'GPL 2.0/LGPL 2.1' +__all__ = ('get_form_template_choices', 'get_success_page_template_choices',) + +from django.utils.translation import ugettext_lazy as _ + +from fobi.base import get_theme +from fobi.contrib.apps.feincms_integration.settings import ( + FORM_TEMPLATE_CHOICES, SUCCESS_PAGE_TEMPLATE_CHOICES +) + +def get_template_choices(choices, theme_specific_choices_key): + """ + Gets the template choices. It's possible to provide theme templates + per theme or just per project. + + :param tuple or list choices: + :param str theme_specific_choices_key: + :return list: + """ + template_choices = [] + if choices: + #template_choices += [(None, _("--- General templates ---"))] + #template_choices += (_("General templates"), list(FORM_TEMPLATE_CHOICES)) + template_choices += list(choices) + + theme = get_theme(as_instance=True) + theme_template_choices = [] + try: + theme_template_choices = list( + theme.custom_data['feincms_integration'][theme_specific_choices_key] + ) + #template_choices += [(None, _("--- Theme templates ---"))] + #template_choices += (_("Theme templates"), theme_template_choices) + template_choices += theme_template_choices + except KeyError: + pass + + return template_choices + +def get_form_template_choices(): + """ + Gets the form template choices. It's possible to provide theme templates + per theme or just per project. + + :return list: + """ + return get_template_choices(FORM_TEMPLATE_CHOICES, 'form_template_choices') + +def get_success_page_template_choices(): + """ + :return list: + """ + return get_template_choices(SUCCESS_PAGE_TEMPLATE_CHOICES, 'success_page_template_choices') diff --git a/src/fobi/contrib/apps/feincms_integration/settings.py b/src/fobi/contrib/apps/feincms_integration/settings.py index ce5c8110d..d764c0ef6 100644 --- a/src/fobi/contrib/apps/feincms_integration/settings.py +++ b/src/fobi/contrib/apps/feincms_integration/settings.py @@ -1,13 +1,14 @@ """ -- `WIDGET_FORM_SENT` (str): Name of the GET param indicating that form has - been successfully sent. +- `WIDGET_FORM_SENT_GET_PARAM` (str): Name of the GET param indicating that + form has been successfully sent. """ __title__ = 'fobi.contrib.apps.feincms_integration.settings' __author__ = 'Artur Barseghyan ' __copyright__ = 'Copyright (c) 2014 Artur Barseghyan' __license__ = 'GPL 2.0/LGPL 2.1' __all__ = ( - 'WIDGET_FORM_SENT_GET_PARAM', + 'WIDGET_FORM_SENT_GET_PARAM', 'FORM_TEMPLATE_CHOICES', + 'SUCCESS_PAGE_TEMPLATE_CHOICES', ) from fobi.contrib.apps.feincms_integration.conf import get_setting @@ -19,3 +20,5 @@ # ************************************************************** WIDGET_FORM_SENT_GET_PARAM = get_setting('WIDGET_FORM_SENT_GET_PARAM') +FORM_TEMPLATE_CHOICES = get_setting('FORM_TEMPLATE_CHOICES') +SUCCESS_PAGE_TEMPLATE_CHOICES = get_setting('SUCCESS_PAGE_TEMPLATE_CHOICES') diff --git a/src/fobi/contrib/apps/feincms_integration/widgets.py b/src/fobi/contrib/apps/feincms_integration/widgets.py index 535ce1bda..d49e462f4 100644 --- a/src/fobi/contrib/apps/feincms_integration/widgets.py +++ b/src/fobi/contrib/apps/feincms_integration/widgets.py @@ -10,7 +10,7 @@ from django.template import RequestContext from django.contrib import messages from django.shortcuts import redirect -from django.core.urlresolvers import reverse +#from django.core.urlresolvers import reverse from django.conf import settings from fobi.dynamic import assemble_form_class @@ -26,13 +26,61 @@ from fobi.contrib.apps.feincms_integration.settings import ( WIDGET_FORM_SENT_GET_PARAM ) +from fobi.contrib.apps.feincms_integration.helpers import ( + get_form_template_choices, get_success_page_template_choices +) class FobiFormWidget(models.Model): """ Widget for to FeinCMS. + + :property fobi.models.FormEntry form_entry: Form entry to be rendered. + :property str template: If given used for rendering the form. """ form_entry = models.ForeignKey('fobi.FormEntry', verbose_name=_("Form")) + form_template_name = models.CharField( + _("Form template name"), max_length=255, null=True, blank=True, + choices=get_form_template_choices(), + help_text=_("Template to render the form with.") + ) + + hide_form_title = models.BooleanField( + _("Hide form title"), default=False, + help_text=_("If checked, no form title is shown.") + ) + + form_title = models.CharField( + _("Form title"), max_length=255, null=True, blank=True, + help_text=_("Overrides the default form title.") + ) + + form_submit_button_text = models.CharField( + _("Submit button text"), max_length=255, null=True, blank=True, + help_text=_("Overrides the default form submit button text.") + ) + + success_page_template_name = models.CharField( + _("Success page template name"), max_length=255, null=True, blank=True, + choices=get_success_page_template_choices(), + help_text=_("Template to render the success page with.") + ) + + hide_success_page_title = models.BooleanField( + _("Hide success page title"), default=False, + help_text=_("If checked, no success page title is shown.") + ) + + success_page_title = models.CharField( + _("Succes page title"), max_length=255, null=True, blank=True, + help_text=_("Overrides the default success page title.") + ) + + success_page_text = models.TextField( + _("Succes page text"), null=True, blank=True, + help_text=_("Overrides the default success page text.") + ) + class Meta: abstract = True app_label = 'fobi' @@ -60,7 +108,7 @@ def _process_form(self, request, **kwargs): :param django.http.HttpRequest request: :return django.http.HttpResponse | str: """ - template_name = None # TODO: fix + template_name = self.form_template_name or None # Handle public/non-public forms. If form requires user authentication # redirect to login form with next parameter set to current request @@ -131,7 +179,7 @@ def _process_form(self, request, **kwargs): request, _('Form {0} was submitted successfully.').format(self.form_entry.name) ) - #return redirect(reverse('fobi.form_entry_submitted', args=[self.form_entry.slug])) + return redirect( "{0}?{1}={2}".format(request.path, WIDGET_FORM_SENT_GET_PARAM, \ self.form_entry.slug) @@ -156,10 +204,13 @@ def _process_form(self, request, **kwargs): 'form': form, 'form_entry': self.form_entry, 'fobi_theme': theme, + 'fobi_form_title': self.form_title, + 'fobi_hide_form_title': self.hide_form_title, + 'fobi_form_submit_button_text': self.form_submit_button_text } if not template_name: - template_name = theme.view_form_entry_ajax_template + template_name = theme.view_embed_form_entry_ajax_template self.rendered_output = render_to_string( template_name, context, context_instance=RequestContext(request) @@ -172,17 +223,20 @@ def _show_thanks_page(self, request, **kwargs): :param django.http.HttpRequest request: :return str: """ - template_name = None # TODO + template_name = self.success_page_template_name or None theme = get_theme(request=request, as_instance=True) context = { 'form_entry': self.form_entry, 'fobi_theme': theme, + 'fobi_hide_success_page_title': self.hide_success_page_title, + 'fobi_success_page_title': self.success_page_title, + 'fobi_success_page_text': self.success_page_text, } if not template_name: - template_name = theme.form_entry_submitted_template + template_name = theme.embed_form_entry_submitted_ajax_template self.rendered_output = render_to_string( template_name, context, context_instance=RequestContext(request) diff --git a/src/fobi/contrib/plugins/form_elements/fields/radio/forms.py b/src/fobi/contrib/plugins/form_elements/fields/radio/forms.py index a4971330e..11e1c1cf4 100644 --- a/src/fobi/contrib/plugins/form_elements/fields/radio/forms.py +++ b/src/fobi/contrib/plugins/form_elements/fields/radio/forms.py @@ -37,21 +37,21 @@ class RadioInputForm(forms.Form, BaseFormFieldPluginForm): choices = forms.CharField( label = _("Choices"), required = False, - help_text = _("Enter either single values or pairs - one per line. Example:
" + help_text = _("Enter single values/pairs per line. Example:
" "    1
" "    2
" "    alpha, Alpha
" "    beta, Beta
" "    omega" "

" - "It finally transforms into the following Python code:
" - '    (
' - '        (1, 1),
' - '        (2, 2),
' - '        ("alpha", "Alpha"),
' - '        ("beta", "Beta"),
' - '        ("omega", "omega"))
' - '    )' + "It finally transforms into the following HTML code:
" + '    <select id="id_NAME_OF_THE_ELEMENT" name="NAME_OF_THE_ELEMENT">
' + '        <option value="1">1</option>
' + '        <option value="2">2</option>
' + '        <option value="alpha">Alpha</option>
' + '        <option value="beta">Beta</option>
' + '        <option value="omega">omega</option>
' + '    </select>' "
"), widget = forms.widgets.Textarea(attrs={'class': theme.form_element_html_class}) ) diff --git a/src/fobi/contrib/themes/bootstrap3/fobi_themes.py b/src/fobi/contrib/themes/bootstrap3/fobi_themes.py index 1ffe7f983..debca9451 100644 --- a/src/fobi/contrib/themes/bootstrap3/fobi_themes.py +++ b/src/fobi/contrib/themes/bootstrap3/fobi_themes.py @@ -81,9 +81,11 @@ class Bootstrap3Theme(BaseTheme): form_entry_submitted_template = 'bootstrap3/form_entry_submitted.html' form_entry_submitted_ajax_template = 'bootstrap3/form_entry_submitted_ajax.html' + embed_form_entry_submitted_ajax_template = 'bootstrap3/embed_form_entry_submitted_ajax.html' view_form_entry_template = 'bootstrap3/view_form_entry.html' view_form_entry_ajax_template = 'bootstrap3/view_form_entry_ajax.html' + view_embed_form_entry_ajax_template = 'bootstrap3/view_embed_form_entry_ajax.html' theme_registry.register(Bootstrap3Theme) diff --git a/src/fobi/contrib/themes/bootstrap3/templates/bootstrap3/embed_form_entry_submitted_ajax.html b/src/fobi/contrib/themes/bootstrap3/templates/bootstrap3/embed_form_entry_submitted_ajax.html new file mode 100644 index 000000000..c96bfec80 --- /dev/null +++ b/src/fobi/contrib/themes/bootstrap3/templates/bootstrap3/embed_form_entry_submitted_ajax.html @@ -0,0 +1 @@ +{% extends "fobi/generic/embed_form_entry_submitted_ajax.html" %} \ No newline at end of file diff --git a/src/fobi/contrib/themes/bootstrap3/templates/bootstrap3/view_embed_form_entry_ajax.html b/src/fobi/contrib/themes/bootstrap3/templates/bootstrap3/view_embed_form_entry_ajax.html new file mode 100644 index 000000000..1deaf8450 --- /dev/null +++ b/src/fobi/contrib/themes/bootstrap3/templates/bootstrap3/view_embed_form_entry_ajax.html @@ -0,0 +1 @@ +{% extends "fobi/generic/view_embed_form_entry_ajax.html" %} \ No newline at end of file diff --git a/src/fobi/templates/fobi/generic/embed_form_entry_submitted_ajax.html b/src/fobi/templates/fobi/generic/embed_form_entry_submitted_ajax.html new file mode 100644 index 000000000..a80a93257 --- /dev/null +++ b/src/fobi/templates/fobi/generic/embed_form_entry_submitted_ajax.html @@ -0,0 +1,9 @@ +{% extends fobi_theme.form_entry_submitted_ajax_template %} + +{% load i18n %} + +{% block form_page_header_wrapper %} + {% if fobi_hide_success_page_title %}{% else %} + {{ block.super }} + {% endif %} +{% endblock %} diff --git a/src/fobi/templates/fobi/generic/form_entry_submitted_ajax.html b/src/fobi/templates/fobi/generic/form_entry_submitted_ajax.html index c81d1b5c2..78c7ed7a1 100644 --- a/src/fobi/templates/fobi/generic/form_entry_submitted_ajax.html +++ b/src/fobi/templates/fobi/generic/form_entry_submitted_ajax.html @@ -1,12 +1,18 @@ {% load i18n %} + {% block form_page_header_wrapper %} + {% endblock form_page_header_wrapper %}

+ {% if fobi_success_page_text %} + {{ fobi_success_page_text }} + {% else %} {% if form_entry.success_page_message %} - {{ form_entry.success_page_message|safe }} + {{ form_entry.success_page_message|safe }} {% else %} - {% blocktrans %}Form submitted successfully.{% endblocktrans %} + {% blocktrans %}Form submitted successfully.{% endblocktrans %} {% endif %} + {% endif %}

diff --git a/src/fobi/templates/fobi/generic/snippets/form_ajax.html b/src/fobi/templates/fobi/generic/snippets/form_ajax.html index eec7ef3ce..b69b2b7d2 100644 --- a/src/fobi/templates/fobi/generic/snippets/form_ajax.html +++ b/src/fobi/templates/fobi/generic/snippets/form_ajax.html @@ -1,6 +1,8 @@ + {% block form_page_header_wrapper %}
-

{% block form_page_title %}{% endblock %}

+ {% block form_page_title_wrapper %}

{% block form_page_title %}{% endblock %}

{% endblock form_page_title_wrapper %}
+ {% endblock form_page_header_wrapper %}
{% csrf_token %} diff --git a/src/fobi/templates/fobi/generic/snippets/form_view_ajax.html b/src/fobi/templates/fobi/generic/snippets/form_view_ajax.html index e0272154c..495111c32 100644 --- a/src/fobi/templates/fobi/generic/snippets/form_view_ajax.html +++ b/src/fobi/templates/fobi/generic/snippets/form_view_ajax.html @@ -1,15 +1,17 @@ + {% block form_page_header_wrapper %}
-

{% block form_page_title %}{% endblock %}

+ {% block form_page_title_wrapper %}

{% block form_page_title %}{% endblock form_page_title %}

{% endblock form_page_title_wrapper %}
+ {% endblock form_page_header_wrapper %} - {% csrf_token %} - {% include fobi_theme.form_view_snippet_template_name %} -
-
- {% block form_buttons %} - - {% endblock form_buttons %} -
+ {% csrf_token %} + {% include fobi_theme.form_view_snippet_template_name %} +
+
+ {% block form_buttons %} + + {% endblock form_buttons %}
+
diff --git a/src/fobi/templates/fobi/generic/view_embed_form_entry_ajax.html b/src/fobi/templates/fobi/generic/view_embed_form_entry_ajax.html new file mode 100644 index 000000000..993007b47 --- /dev/null +++ b/src/fobi/templates/fobi/generic/view_embed_form_entry_ajax.html @@ -0,0 +1,9 @@ +{% extends fobi_theme.view_form_entry_ajax_template %} + +{% load i18n %} + +{% block form_page_header_wrapper %} + {% if fobi_hide_form_title %}{% else %} + {{ block.super }} + {% endif %} +{% endblock %} diff --git a/src/fobi/templates/fobi/generic/view_form_entry_ajax.html b/src/fobi/templates/fobi/generic/view_form_entry_ajax.html index b5839a74a..633add313 100644 --- a/src/fobi/templates/fobi/generic/view_form_entry_ajax.html +++ b/src/fobi/templates/fobi/generic/view_form_entry_ajax.html @@ -3,7 +3,7 @@ {% load i18n %} {% block form_page_title %} -{% trans "View form" %} +{% if fobi_form_title %}{{ fobi_form_title }}{% else %}{% trans "View form" %}{% endif %} {% endblock form_page_title %} -{% block form_primary_button_text %}{% trans "Submit" %}{% endblock %} +{% block form_primary_button_text %}{% if fobi_form_submit_button_text %}{{ fobi_form_submit_button_text }}{% else %}{% trans "Submit" %}{% endif %}{% endblock %}