diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f8378da49..d0ca8a047 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -9,12 +9,14 @@ Changelog * Added thousands separator for counters on dashboard * Added contextual links to admin notification messages * When copying pages, it is now possible to specify a place to copy to (Timo Rieber) + * FieldPanel now accepts an optional 'widget' parameter to override the field's default form widget (Alejandro Giacometti) 0.8.5 (xx.xx.20xx) ~~~~~~~~~~~~~~~~~~ * Fix: On adding a new page, the available page types are ordered by the displayed verbose name * Fix: Active admin submenus were not properly closed when activating another +* Fix: get_sitemap_urls is now called on the specific page class so it can now be overridden (Jerel Unruh) 0.8.4 (04.12.2014) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 85654264d..dae2fd56e 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -38,6 +38,7 @@ Contributors * Robert Rollins * linibou * Timo Rieber +* Jerel Unruh Translators =========== diff --git a/docs/core_components/pages/editing_api.rst b/docs/core_components/pages/editing_api.rst index 94bbb8e88..2087f8c87 100644 --- a/docs/core_components/pages/editing_api.rst +++ b/docs/core_components/pages/editing_api.rst @@ -23,8 +23,10 @@ A "panel" is the basic editing block in Wagtail. Wagtail will automatically pick There are four basic types of panels: - ``FieldPanel( field_name, classname=None )`` - This is the panel used for basic Django field types. ``field_name`` is the name of the class property used in your model definition. ``classname`` is a string of optional CSS classes given to the panel which are used in formatting and scripted interactivity. By default, panels are formatted as inset fields. The CSS class ``full`` can be used to format the panel so it covers the full width of the Wagtail page editor. The CSS class ``title`` can be used to mark a field as the source for auto-generated slug strings. + ``FieldPanel( field_name, classname=None, widget=None )`` + This is the panel used for basic Django field types. ``field_name`` is the name of the class property used in your model definition. ``classname`` is a string of optional CSS classes given to the panel which are used in formatting and scripted interactivity. By default, panels are formatted as inset fields. The CSS class ``full`` can be used to format the panel so it covers the full width of the Wagtail page editor. The CSS class ``title`` can be used to mark a field as the source for auto-generated slug strings. The optional ``widget`` parameter allows you to specify a `django form widget`_ to use instead of the default widget for this field type. + +.. _django form widget: https://docs.djangoproject.com/en/dev/ref/forms/widgets/ ``MultiFieldPanel( children, heading="", classname=None )`` This panel condenses several ``FieldPanel`` s or choosers, from a list or tuple, under a single ``heading`` string. diff --git a/docs/releases/0.8.5.rst b/docs/releases/0.8.5.rst index 447a68d33..9cb718254 100644 --- a/docs/releases/0.8.5.rst +++ b/docs/releases/0.8.5.rst @@ -15,3 +15,4 @@ Bug fixes * On adding a new page, the available page types are ordered by the displayed verbose name * Active admin submenus were not properly closed when activating another +* ``get_sitemap_urls`` is now called on the specific page class so it can now be overridden diff --git a/docs/releases/0.9.rst b/docs/releases/0.9.rst index f70778bd3..c3b0f5c1d 100644 --- a/docs/releases/0.9.rst +++ b/docs/releases/0.9.rst @@ -18,6 +18,7 @@ Minor features * Added thousands separator for counters on dashboard * Added contextual links to admin notification messages * When copying pages, it is now possible to specify a place to copy to + * ``FieldPanel`` now accepts an optional ``widget`` parameter to override the field's default form widget Bug fixes diff --git a/setup.py b/setup.py index b5654c7cc..bd0f4de7f 100644 --- a/setup.py +++ b/setup.py @@ -40,6 +40,7 @@ install_requires = [ "Unidecode>=0.04.14", "six>=1.7.0", 'requests>=2.0.0', + "Willow==0.1", ] diff --git a/tox.ini b/tox.ini index a01c890fe..df523d812 100644 --- a/tox.ini +++ b/tox.ini @@ -17,6 +17,7 @@ base = python-dateutil==2.2 pytz==2014.7 Embedly + Willow==0.1 coverage dj17 = diff --git a/wagtail/contrib/wagtailsitemaps/sitemap_generator.py b/wagtail/contrib/wagtailsitemaps/sitemap_generator.py index d22f88112..e5e43b03e 100644 --- a/wagtail/contrib/wagtailsitemaps/sitemap_generator.py +++ b/wagtail/contrib/wagtailsitemaps/sitemap_generator.py @@ -12,7 +12,7 @@ class Sitemap(object): def get_urls(self): for page in self.get_pages(): - for url in page.get_sitemap_urls(): + for url in page.specific.get_sitemap_urls(): yield url def render(self): diff --git a/wagtail/contrib/wagtailsitemaps/tests.py b/wagtail/contrib/wagtailsitemaps/tests.py index a556ce156..a2d0498d7 100644 --- a/wagtail/contrib/wagtailsitemaps/tests.py +++ b/wagtail/contrib/wagtailsitemaps/tests.py @@ -2,7 +2,7 @@ from django.test import TestCase from django.core.cache import cache from wagtail.wagtailcore.models import Page, PageViewRestriction, Site -from wagtail.tests.models import SimplePage +from wagtail.tests.models import SimplePage, EventIndex from .sitemap_generator import Sitemap @@ -47,6 +47,20 @@ class TestSitemapGenerator(TestCase): self.assertIn('http://localhost/', urls) # Homepage self.assertIn('http://localhost/hello-world/', urls) # Child page + def test_get_urls_uses_specific(self): + # Add an event page which has an extra url in the sitemap + events_page = self.home_page.add_child(instance=EventIndex( + title="Events", + slug='events', + live=True, + )) + + sitemap = Sitemap(self.site) + urls = [url['location'] for url in sitemap.get_urls()] + + self.assertIn('http://localhost/events/', urls) # Main view + self.assertIn('http://localhost/events/past/', urls) # Sub view + def test_render(self): sitemap = Sitemap(self.site) xml = sitemap.render() diff --git a/wagtail/tests/models.py b/wagtail/tests/models.py index 36daf65c9..56b69baa0 100644 --- a/wagtail/tests/models.py +++ b/wagtail/tests/models.py @@ -306,6 +306,15 @@ class EventIndex(Page): for path in super(EventIndex, self).get_static_site_paths(): yield path + def get_sitemap_urls(self): + # Add past events url to sitemap + return super(EventIndex, self).get_sitemap_urls() + [ + { + 'location': self.full_url + 'past/', + 'lastmod': self.latest_revision_created_at + } + ] + EventIndex.content_panels = [ FieldPanel('title', classname="full title"), FieldPanel('intro', classname="full"), diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py index d4eac9fe3..fc7309e76 100644 --- a/wagtail/wagtailadmin/edit_handlers.py +++ b/wagtail/wagtailadmin/edit_handlers.py @@ -362,6 +362,15 @@ def MultiFieldPanel(children, heading="", classname=""): class BaseFieldPanel(EditHandler): + + @classmethod + def widget_overrides(cls): + """check if a specific widget has been defined for this field""" + if hasattr(cls, 'widget'): + return {cls.field_name: cls.widget} + else: + return {} + def __init__(self, instance=None, form=None): super(BaseFieldPanel, self).__init__(instance=instance, form=form) self.bound_field = self.form[self.field_name] @@ -408,11 +417,16 @@ class BaseFieldPanel(EditHandler): return [self.field_name] -def FieldPanel(field_name, classname=""): - return type(str('_FieldPanel'), (BaseFieldPanel,), { +def FieldPanel(field_name, classname="", widget=None): + base = { 'field_name': field_name, 'classname': classname, - }) + } + + if widget: + base['widget'] = widget + + return type(str('_FieldPanel'), (BaseFieldPanel,), base) class BaseRichTextFieldPanel(BaseFieldPanel): diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss index 084a323c8..f9000fb7c 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss @@ -225,13 +225,16 @@ a.tag:hover{ } } +hr{ + border:1px solid $color-grey-4; + border-width:1px 0 0; + margin:1.5em 0; +} /* general image style */ img{ max-width:100%; height:auto; - border: 3px solid $color-grey-4; - } /* make a block-level element inline */ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss index fd0832b70..65abb480b 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/forms.scss @@ -803,8 +803,7 @@ input[type=submit], input[type=reset], input[type=button], .button, button{ .boolean_field &, .choice_field &, .model_choice_field &, - .image_field &, - .file_field &{ + .image_field &{ padding-top:0; } } diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss index af23d45d8..10b4bf7eb 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss @@ -353,6 +353,11 @@ ul.listing{ font-size:1em; opacity:0.7; } + + &.images img{ + @include transition(border-color 0.2s ease); + border: 3px solid transparent; + } } ul.listing{ border-top:1px dashed $color-input-border; diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/tabs.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/tabs.scss index 0473ae050..86f6beb06 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/tabs.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/tabs.scss @@ -66,6 +66,9 @@ content:"w"; margin-right:0.5em; font-size:1.2em; + font-weight:normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } } diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/typography.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/typography.scss index a2d315fc3..0a1b504e8 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/typography.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/typography.scss @@ -58,6 +58,22 @@ kbd{ padding:0.3em 0.5em; } +dl, dt, dd{ + padding:0; + margin:0; +} +dl{ + margin-top:1em; +} +dt{ + color:darken($color-grey-3, 5%); + text-transform:uppercase; + font-size:0.9em; +} +dd{ + margin-bottom:1em; +} + /* Help text formatters */ .help-block{ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss index 40fad99f2..15a7adfc2 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss @@ -314,6 +314,13 @@ footer, .logo{ @include column(12); } + .divider-before{ + border-left:1px solid $color-grey-4; + } + .divider-after{ + border-right:1px solid $color-grey-4; + } + .row{ @include row(); } diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json index 5d9595ecb..02b85fef8 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json @@ -1,7 +1,7 @@ { "metadata": { - "name": "Wagtail 1", - "lastOpened": 1410881728324, + "name": "Wagtail", + "lastOpened": 1420801397108, "created": 1405597423787 }, "iconSets": [ @@ -8564,20 +8564,23 @@ "minorVersion": 0 }, "metrics": { - "emSize": 512, + "emSize": 1024, "baseline": 6.25, "whitespace": 50 }, - "showMetrics": false, + "showMetrics": true, "showMetadata": false, - "showVersion": false + "showVersion": false, + "includeMetadata": false }, "imagePref": {}, "historySize": 100, "showCodes": true, "search": "", "gridSize": 16, - "showGrid": true + "showGrid": true, + "showQuickUse2": true, + "showSVGs": true }, "externalSets": [] } \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot index 8f46b77a4..acbd8ce43 100755 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 a54739410..9dd0ef242 100755 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg @@ -3,75 +3,75 @@ Generated by IcoMoon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf index 85d0d2ab6..7447d813b 100755 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 3680186a1..f8ebc592e 100755 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/page-editor.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/page-editor.scss index 50e77748d..5beae3e39 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/page-editor.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/page-editor.scss @@ -110,6 +110,8 @@ margin:0; cursor:pointer; background-color:$color-salmon; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } } diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/inline_panel_child.html b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/inline_panel_child.html index 0d6bdfde1..b337bba87 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/inline_panel_child.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/inline_panel_child.html @@ -2,10 +2,10 @@
  • {{ child.render_form_content }}
  • diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/create.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/create.html index f21b93a27..7834da176 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/create.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/create.html @@ -3,7 +3,7 @@ {% load i18n %} {% block titletag %}{% blocktrans with page_type=content_type.model_class.get_verbose_name %}New {{ page_type }}{% endblocktrans %}{% endblock %} -{% block bodyclass %}menu-explorer page-editor create{% endblock %} +{% block bodyclass %}menu-explorer page-editor create model-{{ content_type.model }}{% endblock %} {% block content %} @@ -66,4 +66,10 @@ {% endblock %} {% block extra_js %} {% include "wagtailadmin/pages/_editor_js.html" %} + + {% endblock %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/edit.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/edit.html index 51f9d8ba1..f7f0bd9e8 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/edit.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/edit.html @@ -2,8 +2,8 @@ {% load wagtailadmin_tags %} {% load gravatar %} {% load i18n %} -{% block titletag %}{% blocktrans with title=page.title %}Editing {{ title }}{% endblocktrans %}{% endblock %} -{% block bodyclass %}menu-explorer page-editor{% endblock %} +{% block titletag %}{% blocktrans with title=page.title page_type=content_type.model_class.get_verbose_name %}Editing {{ page_type }}: {{ title }}{% endblocktrans %}{% endblock %} +{% block bodyclass %}menu-explorer page-editor model-{{ content_type.model }}{% endblock %} {% block content %} {% page_permissions page as page_perms %} @@ -12,7 +12,7 @@
    -

    {% blocktrans with title=page.title %}Editing {{ title }}{% endblocktrans %}

    +

    {% blocktrans with title=page.title page_type=content_type.model_class.get_verbose_name %}Editing {{ page_type }} {{ title }}{% endblocktrans %}

    {% trans "Status" %} diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/shared/field.html b/wagtail/wagtailadmin/templates/wagtailadmin/shared/field.html index 7c36be5d5..7cb6c05c7 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/shared/field.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/shared/field.html @@ -1,5 +1,5 @@ {% load wagtailadmin_tags %} -
    +
    {{ field.label_tag }}
    diff --git a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py index 4b21fd3c0..cb049d0e8 100644 --- a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py +++ b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py @@ -65,6 +65,14 @@ def fieldtype(bound_field): return "" +@register.filter +def widgettype(bound_field): + try: + return camelcase_to_underscore(bound_field.field.widget.__class__.__name__) + except AttributeError: + return "" + + @register.filter def meta_description(model): try: diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index 873780cdf..65c710e05 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -255,6 +255,8 @@ def edit(request, page_id): page = get_object_or_404(Page, id=page_id).get_latest_revision_as_page() parent = page.get_parent() + content_type = ContentType.objects.get_for_model(page) + page_perms = page.permissions_for_user(request.user) if not page_perms.can_edit(): raise PermissionDenied @@ -373,6 +375,7 @@ def edit(request, page_id): return render(request, 'wagtailadmin/pages/edit.html', { 'page': page, + 'content_type': content_type, 'edit_handler': edit_handler, 'errors_debug': errors_debug, 'preview_modes': page.preview_modes, diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/documents/_file_field.html b/wagtail/wagtaildocs/templates/wagtaildocs/documents/_file_field.html index 13ba6a819..3df57ae30 100644 --- a/wagtail/wagtaildocs/templates/wagtaildocs/documents/_file_field.html +++ b/wagtail/wagtaildocs/templates/wagtaildocs/documents/_file_field.html @@ -1,7 +1,7 @@ -{% extends "wagtailadmin/shared/field_as_li.html" %} +{% extends "wagtailadmin/shared/field.html" %} {% load i18n %} {% block form_field %} - {{ document.file }}

    + {{ document.filename }}

    {% trans "Change document:" %} {{ field }} {% endblock %} diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/documents/_file_field_as_li.html b/wagtail/wagtaildocs/templates/wagtaildocs/documents/_file_field_as_li.html new file mode 100644 index 000000000..0911fc998 --- /dev/null +++ b/wagtail/wagtaildocs/templates/wagtaildocs/documents/_file_field_as_li.html @@ -0,0 +1,4 @@ +{% load wagtailadmin_tags %} +
  • + {% include "wagtaildocs/documents/_file_field.html" %} +
  • \ No newline at end of file diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html b/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html index 62b9df514..9897b41eb 100644 --- a/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html +++ b/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html @@ -15,20 +15,32 @@ {% trans "Editing" as editing_str %} {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=document.title icon="doc-full-inverse" usage_object=document %} -
    -
    - {% csrf_token %} -
      - {% for field in form %} - {% if field.name == 'file' %} - {% include "wagtaildocs/documents/_file_field.html" %} - {% else %} - {% include "wagtailadmin/shared/field_as_li.html" %} - {% endif %} - {% endfor %} -
    • {% trans "Delete document" %}
    • -
    -
    +
    + +
    +
    + {% csrf_token %} +
      + {% for field in form %} + {% if field.name == 'file' %} + {% include "wagtaildocs/documents/_file_field_as_li.html" %} + {% else %} + {% include "wagtailadmin/shared/field_as_li.html" %} + {% endif %} + {% endfor %} +
    • {% trans "Delete document" %}
    • +
    +
    +
    +
    +
    + {% if document.file %} +
    {% trans "Filesize" %}
    +
    {{ document.file.size|filesizeformat }}
    + {% endif %} +
    +
    +
    diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index 27eae6543..a544793fd 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -4,6 +4,7 @@ import re from six import BytesIO, text_type from taggit.managers import TaggableManager +from willow.image import Image as WillowImage from django.core.files import File from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist @@ -80,6 +81,19 @@ class AbstractImage(models.Model, TagSearchable): def __str__(self): return self.title + def get_willow_image(self): + try: + image_file = self.file.file # triggers a call to self.storage.open, so IOErrors from missing files will be raised at this point + except IOError as e: + # re-throw this as a SourceImageIOError so that calling code can distinguish + # these from IOErrors elsewhere in the process + raise SourceImageIOError(text_type(e)) + + image_file.open('rb') + image_file.seek(0) + + return WillowImage.open(image_file) + def get_rect(self): return Rect(0, 0, self.width, self.height) diff --git a/wagtail/wagtailimages/templates/wagtailimages/images/_file_field.html b/wagtail/wagtailimages/templates/wagtailimages/images/_file_field.html index ef61bdacb..4f1d62903 100644 --- a/wagtail/wagtailimages/templates/wagtailimages/images/_file_field.html +++ b/wagtail/wagtailimages/templates/wagtailimages/images/_file_field.html @@ -1,8 +1,10 @@ -{% extends "wagtailadmin/shared/field_as_li.html" %} -{% load i18n %} +{% extends "wagtailadmin/shared/field.html" %} +{% load i18n wagtailimages_tags %} {% block form_field %} - {{ image.filename }}

    + {% image image original as original_image %} - {% trans "Change image:" %} + {{ image.filename }} ({{ original_image.width }}x{{ original_image.height}})

    + + {% trans "Change image file:" %} {{ field }} {% endblock %} diff --git a/wagtail/wagtailimages/templates/wagtailimages/images/_file_field_as_li.html b/wagtail/wagtailimages/templates/wagtailimages/images/_file_field_as_li.html new file mode 100644 index 000000000..bce019852 --- /dev/null +++ b/wagtail/wagtailimages/templates/wagtailimages/images/_file_field_as_li.html @@ -0,0 +1,4 @@ +{% load wagtailadmin_tags %} +
  • + {% include "wagtailimages/images/_file_field.html" %} +
  • \ No newline at end of file diff --git a/wagtail/wagtailimages/templates/wagtailimages/images/edit.html b/wagtail/wagtailimages/templates/wagtailimages/images/edit.html index cd36f9f5c..dd31a1ba5 100644 --- a/wagtail/wagtailimages/templates/wagtailimages/images/edit.html +++ b/wagtail/wagtailimages/templates/wagtailimages/images/edit.html @@ -28,14 +28,14 @@
    -
    +
    {% csrf_token %}
      {% for field in form %} {% if field.name == 'file' %} - {% include "wagtailimages/images/_file_field.html" %} + {% include "wagtailimages/images/_file_field_as_li.html" %} {% elif field.is_hidden %} {{ field }} {% else %} @@ -47,7 +47,7 @@
    -
    +

    {% trans "Focal point (optional)" %}

    {% trans "To define this image's most important region, drag a box over the image below." %} {% if image.focal_point %}({% trans "Current focal point shown" %}){% endif %}

    @@ -64,10 +64,22 @@
    - + +
    +
    {% if url_generator_enabled %} {% trans "URL Generator" %} +
    {% endif %} + + {% image image original as original_image %} + +
    +
    {% trans "Max dimensions" %}
    +
    {{ original_image.width }}x{{ original_image.height }}
    +
    {% trans "Filesize" %}
    +
    {{ image.file.size|filesizeformat }}
    +
    {% endblock %} diff --git a/wagtail/wagtailimages/tests/test_models.py b/wagtail/wagtailimages/tests/test_models.py index 059653681..0d5455840 100644 --- a/wagtail/wagtailimages/tests/test_models.py +++ b/wagtail/wagtailimages/tests/test_models.py @@ -1,4 +1,5 @@ import unittest +from willow.image import Image as WillowImage from django.test import TestCase from django.core.urlresolvers import reverse @@ -13,7 +14,7 @@ from django.db import connection from wagtail.tests.utils import WagtailTestUtils, test_concurrently from wagtail.wagtailcore.models import Page from wagtail.tests.models import EventPage, EventPageCarouselItem -from wagtail.wagtailimages.models import Rendition, Filter +from wagtail.wagtailimages.models import Rendition, Filter, SourceImageIOError from wagtail.wagtailimages.backends import get_image_backend from wagtail.wagtailimages.backends.pillow import PillowBackend from wagtail.wagtailimages.rect import Rect @@ -268,6 +269,29 @@ class TestGetUsage(TestCase): self.assertTrue(issubclass(Page, type(self.image.get_usage()[0]))) +class TestGetWillowImage(TestCase): + fixtures = ['test.json'] + + def setUp(self): + self.image = Image.objects.create( + title="Test image", + file=get_test_image_file(), + ) + + def test_willow_image_object_returned(self): + willow_image = self.image.get_willow_image() + + self.assertIsInstance(willow_image, WillowImage) + + def test_with_missing_image(self): + # Image id=1 in test fixtures has a missing image file + bad_image = Image.objects.get(id=1) + + # Attempting to get the Willow image for images without files + # should raise a SourceImageIOError + self.assertRaises(SourceImageIOError, bad_image.get_willow_image) + + class TestIssue573(TestCase): """ This tests for a bug which causes filename limit on Renditions to be reached