diff --git a/CHANGELOG.txt b/CHANGELOG.txt index bcb58c15b..d8417db22 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -7,6 +7,7 @@ Changelog * Support for alternative image processing backends such as Wand, via the WAGTAILIMAGES_BACKENDS setting * Added support for generating static sites using django-medusa * Added custom Query set for Pages with some handy methods for querying pages + * Added 'wagtailforms' module for creating form pages on a site, and handling form submissions * Editor's guide documentation * Editor interface now outputs form media CSS / JS, to support custom widgets with assets * Migrations and user management now correctly handle custom AUTH_USER_MODEL settings diff --git a/docs/form_builder.rst b/docs/form_builder.rst new file mode 100644 index 000000000..9aa220e19 --- /dev/null +++ b/docs/form_builder.rst @@ -0,0 +1,69 @@ +Form builder +============ + +The `wagtailforms` module allows you to set up single-page forms, such as a 'Contact us' form, as pages of a Wagtail site. It provides a set of base models that site implementors can extend to create their own 'Form' page type with their own site-specific templates. Once a page type has been set up in this way, editors can build forms within the usual page editor, consisting of any number of fields. Form submissions are stored for later retrieval through a new 'Forms' section within the Wagtail admin interface; in addition, they can be optionally e-mailed to an address specified by the editor. + + +Usage +~~~~~ + +Add 'wagtail.wagtailforms' to your INSTALLED_APPS: + +.. code:: python + + INSTALLED_APPS = [ + ... + 'wagtail.wagtailforms', + ] + +Within the models.py of one of your apps, create a model that extends wagtailforms.models.AbstractEmailForm: + + +.. code:: python + + from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField + + class FormField(AbstractFormField): + page = ParentalKey('FormPage', related_name='form_fields') + + class FormPage(AbstractEmailForm): + intro = RichTextField(blank=True) + thank_you_text = RichTextField(blank=True) + + FormPage.content_panels = [ + FieldPanel('title', classname="full title"), + FieldPanel('intro', classname="full"), + InlinePanel(FormPage, 'form_fields', label="Form fields"), + FieldPanel('thank_you_text', classname="full"), + MultiFieldPanel([ + FieldPanel('to_address', classname="full"), + FieldPanel('from_address', classname="full"), + FieldPanel('subject', classname="full"), + ], "Email") + ] + +AbstractEmailForm defines the fields 'to_address', 'from_address' and 'subject', and expects form_fields to be defined. Any additional fields are treated as ordinary page content - note that FormPage is responsible for serving both the form page itself and the landing page after submission, so the model definition should include all necessary content fields for both of those views. + +If you do not want your form page type to offer form-to-email functionality, you can inherit from AbstractForm instead of AbstractEmailForm, and omit the 'to_address', 'from_address' and 'subject' fields from the content_panels definition. + +You now need to create two templates named form_page.html and form_page_landing.html (where 'form_page' is the underscore-formatted version of the class name). form_page.html differs from a standard Wagtail template in that it is passed a variable 'form', containing a Django form object, in addition to the usual 'self' variable. A very basic template for the form would thus be: + +.. code:: html + + {% load pageurl rich_text %} + + + {{ self.title }} + + +

{{ self.title }}

+ {{ self.intro|richtext }} +
+ {% csrf_token %} + {{ form.as_p }} + +
+ + + +form_page_landing.html is a regular Wagtail template, displayed after the user makes a successful form submission. diff --git a/docs/index.rst b/docs/index.rst index 5b2b62bc4..bdcd6a517 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,6 +13,7 @@ It supports Django 1.6.2+ on Python 2.6 and 2.7. Django 1.7 and Python 3 support wagtail_search deploying performance + form_builder static_site_generation contributing support diff --git a/docs/roadmap.rst b/docs/roadmap.rst index c94692fac..bdc711470 100644 --- a/docs/roadmap.rst +++ b/docs/roadmap.rst @@ -10,7 +10,7 @@ https://raw.github.com/torchbox/wagtail/master/CHANGELOG.txt In summary: - * February 2013: Reduced dependencies, basic documentation, translations, tests + * February 2014: Reduced dependencies, basic documentation, translations, tests What's next ~~~~~~~~~~~ @@ -19,12 +19,10 @@ The `issue list `_ gives a detailed * More and better tests (>80% `coverage `_) * Better documentation: simple setup guides for all levels of user, a manual for editors and administrators, in-depth intstructions for Django developers. - * A form builder * Move site section permissions out of Django admin * Improved image handling: intelligent cropping, animated gif support * Block-level editing UI (see `Sir Trevor `_) * Site settings management - * Edit bird for logged-in visitors * Support for an HTML content type * Simple inline stats diff --git a/runtests.py b/runtests.py index ab7bc37c3..1577d73b5 100755 --- a/runtests.py +++ b/runtests.py @@ -80,6 +80,7 @@ if not settings.configured: 'wagtail.wagtailembeds', 'wagtail.wagtailsearch', 'wagtail.wagtailredirects', + 'wagtail.wagtailforms', 'wagtail.tests', ], diff --git a/setup.py b/setup.py index e8da542bc..8a85f618c 100644 --- a/setup.py +++ b/setup.py @@ -51,6 +51,7 @@ setup( "Pillow>=2.3.0", "beautifulsoup4>=4.3.2", "lxml>=3.3.0", + 'unicodecsv>=0.9.4', 'Unidecode>=0.04.14', "BeautifulSoup==3.2.1", # django-compressor gets confused if we have lxml but not BS3 installed ], diff --git a/wagtail/tests/fixtures/test.json b/wagtail/tests/fixtures/test.json index 0a0fc0528..625c5618b 100644 --- a/wagtail/tests/fixtures/test.json +++ b/wagtail/tests/fixtures/test.json @@ -23,7 +23,7 @@ "model": "wagtailcore.page", "fields": { "title": "Welcome to the Wagtail test site!", - "numchild": 1, + "numchild": 3, "show_in_menus": false, "live": true, "depth": 2, @@ -164,6 +164,57 @@ } }, +{ + "pk": 8, + "model": "wagtailcore.page", + "fields": { + "title": "Contact us", + "numchild": 0, + "show_in_menus": true, + "live": true, + "depth": 3, + "content_type": ["tests", "formpage"], + "path": "000100010003", + "url_path": "/home/contact-us/", + "slug": "contact-us" + } +}, +{ + "pk": 8, + "model": "tests.formpage", + "fields": { + } +}, + +{ + "pk": 1, + "model": "tests.formfield", + "fields": { + "sort_order": 1, + "label": "Your email", + "field_type": "email", + "required": true, + "choices": "", + "default_value": "", + "help_text": "", + "page": 8 + } +}, +{ + "pk": 2, + "model": "tests.formfield", + "fields": { + "sort_order": 2, + "label": "Your message", + "field_type": "multiline", + "required": true, + "choices": "", + "default_value": "", + "help_text": "", + "page": 8 + } +}, + { "pk": 1, "model": "wagtailcore.site", @@ -201,6 +252,19 @@ ] } }, +{ + "pk": 5, + "model": "auth.group", + "fields": { + "name": "Site-wide editors", + "permissions": [ + ["access_admin", "wagtailadmin", "admin"], + ["add_image", "wagtailimages", "image"], + ["change_image", "wagtailimages", "image"], + ["delete_image", "wagtailimages", "image"] + ] + } +}, { "pk": 1, "model": "wagtailcore.grouppagepermission", @@ -237,6 +301,15 @@ "permission_type": "publish" } }, +{ + "pk": 5, + "model": "wagtailcore.grouppagepermission", + "fields": { + "group": ["Site-wide editors"], + "page": 2, + "permission_type": "edit" + } +}, { "pk": 1, @@ -308,5 +381,42 @@ "password": "md5$seasalt$1e9bf2bf5606aa5c39852cc30f0f6f22", "email": "inactiveuser@example.com" } +}, +{ + "pk": 5, + "model": "auth.user", + "fields": { + "username": "siteeditor", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": false, + "is_staff": false, + "groups": [ + ["Site-wide editors"] + ], + "user_permissions": [], + "password": "md5$seasalt$1e9bf2bf5606aa5c39852cc30f0f6f22", + "email": "siteeditor@example.com" + } +}, + +{ + "pk": 1, + "model": "wagtailforms.formsubmission", + "fields": { + "form_data": "{\"your-email\": \"old@example.com\", \"your-message\": \"this is a really old message\"}", + "page": 8, + "submit_time": "2013-01-01T12:00:00.000Z" + } +}, +{ + "pk": 2, + "model": "wagtailforms.formsubmission", + "fields": { + "form_data": "{\"your-email\": \"new@example.com\", \"your-message\": \"this is a fairly new message\"}", + "page": 8, + "submit_time": "2014-01-01T12:00:00.000Z" + } } ] diff --git a/wagtail/tests/models.py b/wagtail/tests/models.py index 97858df4d..844fb836f 100644 --- a/wagtail/tests/models.py +++ b/wagtail/tests/models.py @@ -6,6 +6,7 @@ from wagtail.wagtailcore.fields import RichTextField from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, InlinePanel, PageChooserPanel from wagtail.wagtailimages.edit_handlers import ImageChooserPanel from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel +from wagtail.wagtailforms.models import AbstractEmailForm, AbstractFormField EVENT_AUDIENCE_CHOICES = ( @@ -234,3 +235,20 @@ EventIndex.content_panels = [ FieldPanel('title', classname="full title"), FieldPanel('intro', classname="full"), ] + + +class FormField(AbstractFormField): + page = ParentalKey('FormPage', related_name='form_fields') + +class FormPage(AbstractEmailForm): + pass + +FormPage.content_panels = [ + FieldPanel('title', classname="full title"), + InlinePanel(FormPage, 'form_fields', label="Form fields"), + MultiFieldPanel([ + FieldPanel('to_address', classname="full"), + FieldPanel('from_address', classname="full"), + FieldPanel('subject', classname="full"), + ], "Email") +] diff --git a/wagtail/tests/templates/tests/form_page.html b/wagtail/tests/templates/tests/form_page.html new file mode 100644 index 000000000..5fbd2ae9f --- /dev/null +++ b/wagtail/tests/templates/tests/form_page.html @@ -0,0 +1,15 @@ +{% load pageurl %} + + + + {{ self.title }} + + +

{{ self.title }}

+
+ {% csrf_token %} + {{ form.as_p }} + +
+ + diff --git a/wagtail/tests/templates/tests/form_page_landing.html b/wagtail/tests/templates/tests/form_page_landing.html new file mode 100644 index 000000000..e29a6a942 --- /dev/null +++ b/wagtail/tests/templates/tests/form_page_landing.html @@ -0,0 +1,11 @@ +{% load pageurl %} + + + + {{ self.title }} + + +

{{ self.title }}

+

Thank you for your feedback.

+ + diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/core.js b/wagtail/wagtailadmin/static/wagtailadmin/js/core.js index e5895e34f..380c3d179 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/js/core.js +++ b/wagtail/wagtailadmin/static/wagtailadmin/js/core.js @@ -128,7 +128,7 @@ $(function(){ $(window.headerSearch.termInput).trigger('focus'); function search () { - var workingClasses = "working icon icon-spinner"; + var workingClasses = "icon-spinner"; $(window.headerSearch.termInput).parent().addClass(workingClasses); search_next_index++; diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss index 569821e10..bc2b02a8c 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss @@ -177,4 +177,9 @@ a.tag:hover{ /* make a block-level element inline */ .inline{ display:inline; +} + +/* utility class to allow things to be scrollable if their contents can't wrap more nicely */ +.overflow{ + overflow:auto; } \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss index 9ef27297c..29c44b4f3 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss @@ -21,22 +21,13 @@ legend{ @include visuallyhidden(); } -.fields li{ - padding-top:0.5em; - padding-bottom:0.5em; -} - -.field{ - padding:0 0 0.6em 0; -} - label{ font-weight:bold; color:$color-grey-1; font-size:1.1em; display:block; padding:0 0 0.8em 0; - line-height:1em; + line-height:1.3em; .checkbox &, .radio &{ @@ -47,10 +38,10 @@ label{ input, textarea, select, .richtext, .tagit{ @include border-radius(6px); @include border-box(); - font-family:Open Sans,Arial,sans-serif; width:100%; - border:1px dashed $color-input-border; - padding:1.2em; + font-family:Open Sans,Arial,sans-serif; + border:1px solid $color-input-border; + padding:0.9em 1.2em; background-color:$color-fieldset-hover; -webkit-appearance: none; color:$color-text-input; @@ -76,10 +67,44 @@ input, textarea, select, .richtext, .tagit{ } } -input[type=radio],input[type=checkbox]{ +/* select boxes */ +.typed_choice_field .input{ + position:relative; + + select{ + outline:none; + } + + &:after{ + @include border-radius(0 6px 6px 0); + z-index:0; + position:absolute; + right:1px; + top:1px; + height:95%; + width:1.5em; + font-family:wagtail; + content:"q"; + border:1px solid $color-input-border; + border-width:0 0 0 1px; + text-align:center; + line-height:1.4em; + font-size:3em; + pointer-events:none; + color:$color-grey-3; + background-color:$color-fieldset-hover; + margin:0px 1px 0 0; + } + + .ie &:after{ + display:none; + } +} + +/* radio and check boxes */ +input[type=radio], input[type=checkbox]{ @include border-radius(0); cursor:pointer; - float:left; border:0; } @@ -350,18 +375,15 @@ button.icon{ .help, .error-message{ font-size:0.85em; font-weight:normal; - margin:0 0 0.5em 0; + margin:0.5em 0 0 0; +} +.error-message{ + color:$color-red; } .help{ color:$color-grey-2; } -/* permanently show checkbox/radio help as they have no focus state */ -.boolean_field .help, .radio .help{ - opacity:1; -} - - fieldset:hover > .help, .field.focused + .help, .field:focus + .help, @@ -380,18 +402,77 @@ li.focused > .help{ font-size:13px; } -.error-message{ - margin:0; - color:$color-red; - clear:both; -} - .error input, .error textarea, .error select, .error .tagit{ border-color:$color-red; background-color:$color-input-error-bg; } +/* Layouts for particular kinds of of fields */ + +/* permanently show checkbox/radio help as they have no focus state */ +.boolean_field .help, .radio .help{ + opacity:1; +} +.iconfield { + position:relative; + + input:not([type=radio]), input:not([type=checkbox]), input:not([type=submit]), input:not([type=button]){ + padding-left:2.5em; + } + + &:before, &:after{ + font-family:wagtail; + position:absolute; + top:0.4em; + font-size:1.4em; + color:$color-grey-3; + } + &:before{ + left:0.5em; + } + &:after{ + right:0.5em; + } + + /* special case for search spinners */ + &.icon-spinner:after{ + color:$color-teal; + opacity:0.8; + font-size:20px; + width:20px; + height:20px; + line-height:23px; + text-align:center; + top:0.3em; + + } +} + +.fields li{ + padding-top:0.5em; + padding-bottom:1.2em; +} + +.field-content .input li{ + label{ + width:auto; + float:none; + } +} + +.input{ + clear:both; +} + /* field sizing */ + +.field-small{ + input, textarea, select, .richtext, .tagit{ + @include border-radius(3px); + padding:0.4em 1em; + } +} + .field{ &.col1, &.col2, @@ -453,7 +534,7 @@ ul.inline li:first-child, li.inline:first-child{ display:block; float:left; color:$color-grey-3; - line-height:0.85em; + line-height:1em; font-size:2.5em; margin-right:0.3em; } @@ -495,7 +576,6 @@ ul.inline li:first-child, li.inline:first-child{ .unchosen, .chosen{ &:before{ content:"b"; - margin-left:-0.1em; /* this glyphs appear to have left padding, counteracted here */ } } } @@ -568,112 +648,6 @@ ul.tagit li.tagit-choice-editable{ } } - -/* search bars (search integrated into header area) */ -.search-bar{ - margin-top:-2em; - padding-top:1em; - padding-bottom:1em; - margin-bottom:2em; - - &.full-width{ - @include nice-padding(); - background-color:$color-header-bg; - border-bottom:1px solid $color-grey-4; - } - - label{ - display:none; - } - - .fields{ - position:relative; - clear:both; - - .field input{ - padding-left:3em; - - &:focus{ - background-color:white; - } - } - .field:before, .field:after{ - font-family:wagtail; - position:absolute; - top:1em; - font-size:25px; - - } - .field:before{ - left:0.5em; - content:"f"; - color:$color-grey-3; - } - .field:after{ - color:$color-teal; - opacity:0.8; - font-size:20px; - width:20px; - height:20px; - line-height:23px; - text-align:center; - top:0.3em; - right:0.5em; - } - } - .submit{ - display:none; - position:absolute; - right:0; - top:0; - input{ - padding:1.55em 2em; - } - } - .taglist{ - font-size:0.9em; - line-height:2.4em; - h3{ - display:inline; - } - a{ - white-space: nowrap - } - } - - &.small{ - margin:0; - padding:0; - .fields{ - li{ - padding:0; - } - .field{ - padding:0; - } - .field input{ - padding:0.4em 1.4em 0.4em 2em; - - &:focus{ - background-color:white; - } - } - .field:before{ - font-size:1.1rem; - top:0.45em; - } - - } - } -} - -/* mozilla specific hack */ -@-moz-document url-prefix() { - .search-bar .fields .field:after{ - line-height:20px; - } -} - /* Transitions */ fieldset, input, textarea, select{ @include transition(background-color 0.2s ease); @@ -686,11 +660,22 @@ input[type=submit], input[type=reset], input[type=button], .button, button{ } @media screen and (min-width: $breakpoint-mobile){ - .help{ - opacity:1; - } - .fields{ - max-width:800px; + label{ + @include column(2); + padding-top:1.2em; + padding-left:0; + + .model_multiple_choice_field &, + .boolean_field &, + .model_choice_field &, + .image_field &, + .file_field &{ + padding-top:0; + } + + .boolean_field &{ + padding-bottom:0; + } } input[type=submit], input[type=reset], input[type=button], .button, button{ @@ -706,4 +691,20 @@ input[type=submit], input[type=reset], input[type=button], .button, button{ } } } + + .help{ + opacity:1; + } + .fields{ + max-width:800px; + } + + .field{ + @include row(); + } + + .field-content{ + @include column(10); + padding-right:0; + } } \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/header.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/header.scss new file mode 100644 index 000000000..849420ae0 --- /dev/null +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/header.scss @@ -0,0 +1,156 @@ +header{ + padding-top:1em; + padding-bottom:1em; + background-color: $color-header-bg; + margin-bottom:2em; + color:white; + + h1, h2{ + margin:0; + color:white; + } + + h1{ + padding:0.2em 0; + + &.icon:before{ + width:1em; + display:none; + margin-right:0.4em; + font-size:1.5em; + } + } + + .col{ + float:left; + margin-right:2em; + } + .left{ + float:left; + + .hasform &:first-child{ + padding-bottom:0.5em; + float:none; + } + } + .right{ + text-align:right; + float:right; + } + + /* For case where content below header should merge with it */ + &.merged{ + margin-bottom:0; + } + &.tab-merged, &.no-border{ + border:0; + } + &.merged.no-border{ + padding-bottom:0; + } + &.no-v-padding{ + padding-top:0; + padding-bottom:0; + } + /* + &.hasform h1{ + margin-top:0.2em; + } + */ + .button{ + background-color:$color-teal-darker; + &:hover{ + background-color:$color-teal-dark; + } + } + + /* necessary on mobile only to make way for hamburger menu */ + &.nice-padding{ + padding-left:4em; + } + + label{ + @include visuallyhidden(); + } + + input[type=text], select{ + border-width:0; + + &:focus{ + background-color:white; + } + } + + .fields{ + margin-top:-0.5em; + li{ + padding-bottom:0; + } + .field{ + padding:0; + } + } + + .field-content{ + width:auto; + padding:0; + } +} + +/* mozilla specific hack */ +@-moz-document url-prefix() { + .iconfield.icon-spinner:after{ + line-height:20px; + } +} + +.page-explorer header{ + margin-bottom:0; + padding-bottom:0em; +} + + +@media screen and (min-width: $breakpoint-mobile){ + header{ + padding-top:1.5em; + padding-bottom:1.5em; + + .left{ + float:left; + margin-right:0; + + &:first-child{ + padding-bottom:0; + float:left; + } + } + .second{ + clear:none; + + .right, .left{ + float:right; + } + } + + h1.icon:before{ + display:inline-block; + } + + .col3{ + @include column(3); + } + .col3.addbutton{ + width:auto; + } + .col6{ + @include column(6); + } + .col9{ + @include column(9); + } + .breadcrumb{ + margin-left:-($desktop-nice-padding); + margin-right:-($desktop-nice-padding); + } + } +} \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss index 9a1351d9a..4de3aa131 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss @@ -231,14 +231,20 @@ .icon-collapse-up:before{ content:"6"; } +.icon-date:before{ + content:"7"; +} +.icon-success:before{ + content:"9"; +} .icon-help:before{ content:"?"; } .icon-warning:before{ content:"!"; } -.icon-success:before{ - content:"9"; +.icon-form:before{ + content:"$"; } .icon.text-replace{ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss index 2c1232091..e622680bd 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss @@ -11,6 +11,7 @@ @import "components/listing.scss"; @import "components/messages.scss"; @import "components/formatters.scss"; +@import "components/header.scss"; @import "fonts.scss"; @@ -385,88 +386,6 @@ body.explorer-open { } } -header{ - padding-top:1em; - padding-bottom:1em; - background-color: $color-header-bg; - margin-bottom:2em; - color:white; - - h1, h2{ - margin:0; - color:white; - } - - h1{ - padding:0.2em 0; - - &.icon:before{ - width:1em; - display:none; - margin-right:0.4em; - font-size:1.3em; - } - } - - .col{ - float:left; - margin-right:2em; - } - .left{ - float:left; - - .hasform &:first-child{ - padding-bottom:0.5em; - float:none; - } - } - .search-bar input{ - @include border-radius(3px); - width:auto; - border-width:0; - } - .right{ - text-align:right; - float:right; - } - - /* For case where content below header should merge with it */ - &.merged{ - margin-bottom:0; - } - &.tab-merged, &.no-border{ - border:0; - } - &.merged.no-border{ - padding-bottom:0; - } - &.no-v-padding{ - padding-top:0; - padding-bottom:0; - } - /* - &.hasform h1{ - margin-top:0.2em; - } - */ - .button{ - background-color:$color-teal-darker; - &:hover{ - background-color:$color-teal-dark; - } - } - /* necessary on mobile only to make way for hamburger menu */ - &.nice-padding{ - padding-left:4em; - } -} - -.page-explorer header{ - margin-bottom:0; - padding-bottom:0em; -} - - footer{ @include row(); @include border-radius(3px 3px 0 0); @@ -832,52 +751,6 @@ footer, .logo{ } } - header{ - padding-top:1.5em; - padding-bottom:1.5em; - - &.nice-padding{ - @include nice-padding(); - } - - .left{ - float:left; - margin-right:0; - - &:first-child{ - padding-bottom:0; - float:left; - } - } - .second{ - clear:none; - - .right, .left{ - float:right; - } - } - - h1.icon:before{ - display:inline-block; - } - - .col3{ - @include column(3); - } - .col3.addbutton{ - width:auto; - } - .col6{ - @include column(6); - } - .col9{ - @include column(9); - } - .breadcrumb{ - margin-left:-($desktop-nice-padding); - margin-right:-($desktop-nice-padding); - } - } footer{ width:80%; margin-left:50px; diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot index f55be6906..6ac63514a 100644 Binary files a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot and b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot differ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg index 188de85f2..9bded54bf 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg @@ -67,6 +67,8 @@ - + + + diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf index a401ae2dd..2006feefb 100644 Binary files a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf and b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf differ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.woff b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.woff index fbefc159a..072c20a16 100644 Binary files a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.woff and b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.woff differ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/login.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/login.scss index 4abf3ae20..3e158e51f 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/login.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/login.scss @@ -82,7 +82,7 @@ form{ .field{ padding:0; } - .field.icon:before{ + .iconfield:before{ display:none; } @@ -168,25 +168,29 @@ form{ font-size:4em; } - .field.icon:before{ - display:inline-block; - position: absolute; - color:$color-grey-4; - border: 2px solid $color-grey-4; - border-radius: 100%; - width: 1em; - padding: 0.3em; - left: $desktop-nice-padding; - margin-top: -1em; - top: 50%; - font-size:1.5em; - } - .full{ margin:0px (-$desktop-nice-padding); - input{ - padding-left:($desktop-nice-padding + 50px); + .iconfield{ + &:before{ + display:inline-block; + position: absolute; + color:$color-grey-4; + border: 2px solid $color-grey-4; + border-radius: 100%; + width: 1em; + padding: 0.3em; + left: $desktop-nice-padding; + margin-top: -1.1rem; + top: 50%; + font-size:1.3rem; + } + + input{ + padding-left:($desktop-nice-padding + 50px); + } } + + } } \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/page-editor.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/page-editor.scss index e7fa55c7c..c9a22b3ac 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/page-editor.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/page-editor.scss @@ -148,7 +148,6 @@ display:block; float:none; - .help{ display:none; } @@ -343,6 +342,10 @@ footer .preview{ @include column(10); padding-left:0; padding-right:0; + + fieldset{ + width:100%; + } } .object-help{ @@ -371,6 +374,12 @@ footer .preview{ .field{ padding:0; } + .field-content{ + display: block; + float: none; + width: auto; + padding: inherit; + } } .multiple{ @include column(10); @@ -381,5 +390,12 @@ footer .preview{ &.empty .add{ margin:0 0 0 -50px; } + + &.single-field label{ + display: block; + float: none; + width: auto; + padding:auto; + } } } diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss index 3533bd876..4c06efec8 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss @@ -42,7 +42,7 @@ $color-grey-5: #fafafa; $color-thead-bg: $color-grey-5; $color-header-bg: $color-teal; // #ff6a58; $color-fieldset-hover: $color-grey-5; -$color-input-border: $color-grey-3; +$color-input-border: $color-grey-4; $color-input-focus: #f4fcfc; $color-input-error-bg: #feedee; $color-button: $color-teal; diff --git a/wagtail/wagtailadmin/tasks.py b/wagtail/wagtailadmin/tasks.py index 3d6f3e8f1..59779d36b 100644 --- a/wagtail/wagtailadmin/tasks.py +++ b/wagtail/wagtailadmin/tasks.py @@ -85,3 +85,16 @@ def send_notification(page_revision_id, notification, excluded_user_id): # Send email send_mail(email_subject, email_content, from_email, email_addresses) + + +@task +def send_email_task(email_subject, email_content, email_addresses, from_email=None): + if not from_email: + if hasattr(settings, 'WAGTAILADMIN_NOTIFICATION_FROM_EMAIL'): + from_email = settings.WAGTAILADMIN_NOTIFICATION_FROM_EMAIL + elif hasattr(settings, 'DEFAULT_FROM_EMAIL'): + from_email = settings.DEFAULT_FROM_EMAIL + else: + from_email = 'webmaster@localhost' + + send_mail(email_subject, email_content, from_email, email_addresses) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/field_panel_field.html b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/field_panel_field.html index 602efa583..472cae0b2 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/field_panel_field.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/field_panel_field.html @@ -1,18 +1,23 @@
- {% if field_type != "boolean_field" %}{{ field.label_tag }}{% endif %} - {% block form_field %} - {{ field }} - {% endblock %} - {% if field_type = "boolean_field" %}{{ field.label_tag }}{% endif %} + {{ field.label_tag }} +
+
+ {% block form_field %} + {{ field }} + {% endblock %} + +
+ {% if field.help_text %} +

{{ field.help_text }}

+ {% endif %} + + {% if field.errors %} +

+ {% for error in field.errors %} + {{ error }} + {% endfor %} +

+ {% endif %} +
-{% if field.errors %} -

- {% for error in field.errors %} - {{ error }} - {% endfor %} -

-{% endif %} -{% if field.help_text %} -

{{ field.help_text }}

-{% endif %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/login.html b/wagtail/wagtailadmin/templates/wagtailadmin/login.html index 9cb28ed86..012dd32f8 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/login.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/login.html @@ -28,15 +28,19 @@
  • -
    +
    {{ form.username.label_tag }} - {{ form.username }} +
    + {{ form.username }} +
  • -
    +
    {{ form.password.label_tag }} - {{ form.password }} +
    + {{ form.password }} +
    {% if show_password_reset %}

    {% trans "Forgotten it?" %}

    diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/shared/field_as_li.html b/wagtail/wagtailadmin/templates/wagtailadmin/shared/field_as_li.html index af4ba73a3..678dd67fd 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/shared/field_as_li.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/shared/field_as_li.html @@ -1,21 +1,25 @@ {% load wagtailadmin_tags %} -
  • +
  • - {% if field|fieldtype != "boolean_field" %}{{ field.label_tag }}{% endif %} - {% block form_field %} - {{ field }} - {% endblock %} - {% if field|fieldtype = "boolean_field" %}{{ field.label_tag }}{% endif %} -
    + {{ field.label_tag }} +
    +
    + {% block form_field %} + {{ field }} + {% endblock %} + +
    + {% if field.help_text %} +

    {{ field.help_text }}

    + {% endif %} - {% if field.errors %} -

    - {% for error in field.errors %} - {{ error|escape }} - {% endfor %} -

    - {% endif %} - {% if field.help_text %} -

    {{ field.help_text }}

    - {% endif %} + {% if field.errors %} +

    + {% for error in field.errors %} + {{ error|escape }} + {% endfor %} +

    + {% endif %} +
    +
  • \ No newline at end of file diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html b/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html index 3ea5d4d10..59340d2d8 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html @@ -5,12 +5,12 @@

    {{ title }} {{ subtitle }}

    {% if search_url %} - {% endif %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/shared/pagination_nav.html b/wagtail/wagtailadmin/templates/wagtailadmin/shared/pagination_nav.html index 39eb88a15..ca3e4b073 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/shared/pagination_nav.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/shared/pagination_nav.html @@ -1,4 +1,16 @@ {% load i18n %} +{% if not is_ajax %} + {% comment %} + HACK: This template expects to be passed a 'linkurl' parameter, containing a URL name + that can be reverse-resolved by the {% url %} tag with no further parameters. + Views that have parameters in their URL can work around this by passing a bogus + (but non-blank) URL name, which will return an empty string and produce a final URL + of the form "?q=123", implicitly preserving the current URL path. + Using the {% url ... as ... %} form of the tag ensures that this fails silently, + rather than throwing a NoReverseMatch exception. + {% endcomment %} + {% url linkurl as url_to_use %} +{% endif %}