mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-05-14 10:13:13 +00:00
Merge remote-tracking branch 'upstream/master' into fixbug-1298
This commit is contained in:
commit
fce071d64e
667 changed files with 15247 additions and 6780 deletions
|
|
@ -1,7 +0,0 @@
|
|||
image: wagtail-ci
|
||||
script:
|
||||
- python3.4 setup.py install
|
||||
- pip3.4 install -r requirements-dev.txt
|
||||
- python3.4 runtests.py --keepdb
|
||||
env:
|
||||
- DATABASE_NAME=/base-dbs/wagtail.v1.0.sqlite
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
language: python
|
||||
|
||||
# Use container-based infrastructure
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env: TOXENV=py27-dj17-postgres
|
||||
|
|
|
|||
12
.tx/config
12
.tx/config
|
|
@ -66,3 +66,15 @@ file_filter = wagtail/wagtailsites/locale/<lang>/LC_MESSAGES/django.po
|
|||
source_file = wagtail/wagtailsites/locale/en/LC_MESSAGES/django.po
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[wagtail.wagtailsearchpromotions]
|
||||
file_filter = wagtail/contrib/wagtailsearchpromotions/locale/<lang>/LC_MESSAGES/django.po
|
||||
source_file = wagtail/contrib/wagtailsearchpromotions/locale/en/LC_MESSAGES/django.po
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[wagtail.wagtailstyleguide]
|
||||
file_filter = wagtail/contrib/wagtailstyleguide/locale/<lang>/LC_MESSAGES/django.po
|
||||
source_file = wagtail/contrib/wagtailstyleguide/locale/en/LC_MESSAGES/django.po
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
1.2 (xx.xx.xxxx)
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix: Deleting a page permission from the groups admin UI does not immediately submit the form
|
||||
|
||||
|
||||
1.1 (xx.xx.xxxx)
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Implemented the `specific()` method on PageQuerySet, to return pages as their most specific type
|
||||
* "Promoted search results" has moved into its own module
|
||||
* Elasticsearch backend now supports an experimental `ATOMIC_REBUILD` flag to keep the existing index available while the `update_index` task is running
|
||||
* The wagtailapi module has been refactored to use Django REST Framework
|
||||
* The wagtailapi module has been refactored to use Django REST Framework (Tom Christie)
|
||||
* A number of permissions fixes have been made to the Wagtail admin interface. See release notes for a list of specific changes made.
|
||||
* Snippets that inherit from `wagtail.wagtailsearch.index.Indexed` now appear as searchable within the Wagtail admin
|
||||
* Implemented deletion of form submissions (Kyungil Choi)
|
||||
* Implemented pagination in the page chooser modal
|
||||
* Changed INSTALLED_APPS in project template to list apps in precedence order (Piet Delport)
|
||||
* The `{% image %}` tag now supports filters on the image variable, e.g. `{% image primary_img|default:secondary_img width-500 %}`
|
||||
|
|
@ -17,11 +26,33 @@ Changelog
|
|||
* Added optional directory argument to "wagtail start" command (Mitchel Cabuloy)
|
||||
* Non-superusers can now view/edit/delete sites if they have the correct permissions
|
||||
* Image file size is now stored in the database, to avoid unnecessary filesystem lookups
|
||||
* Page URL lookups hit the cache/database less often (Michael van Tellingen)
|
||||
* Updated URLs within the admin backend to use namespaces
|
||||
* The `update_index` task now indexes objects in batches of 1000, to indicate progress and avoid excessive memory use
|
||||
* Added database indexes on PageRevision and Image to improve performance on large sites
|
||||
* Search in page chooser now uses Wagtail's search framework, to order results by relevance
|
||||
* `PageChooserPanel` now supports passing a list (or tuple) of accepted page types
|
||||
* The snippet type parameter of `SnippetChooserPanel` can now be omitted, or passed as a model name string rather than a model class (Joss Ingram)
|
||||
* Added aliases for the `self` template variable to accommodate Jinja as a templating engine: `page` for pages, `field_panel` for field panels / edit handlers, and `value` for blocks
|
||||
* Added signposting text to the explorer to steer editors away from creating pages at the root level unless they are setting up new sites
|
||||
* "Clear choice" and "Edit this page" buttons are no longer shown on the page field of the group page permissions form
|
||||
* Altered styling of stream controls to be more like all other buttons
|
||||
* Added ability to mark page models as not available for creation using the flag `is_creatable`; pages that are abstract Django models are automatically made non-creatable
|
||||
* New translations for Norwegian Bokmål and Icelandic
|
||||
* Fix: Text areas in the non-default tab of the page editor now resize to the correct height
|
||||
* Fix: Tabs in "insert link" modal in the rich text editor no longer disappear (Tim Heap)
|
||||
* Fix: H2 elements in rich text fields were accidentally given a click() binding when put insite a collapsible multi field panel
|
||||
* Fix: The wagtailimages module is now compatible with remote storage backends that do not allow reopening closed files
|
||||
* Fix: Search no longer crashes when auto-indexing a model that doesn't have an id field (Scot Hacker)
|
||||
* Fix: The `wagtailfrontendcache` module's HTTP backend has been rewritten to reliably direct requests to the configured cache hostname
|
||||
* Fix: Resizing single pixel images with the "fill" filter no longer raises "ZeroDivisionError" or "tile cannot extend outside image"
|
||||
* Fix: The queryset returned from `search` operations when using the database search backend now correctly preserves additional properties of the original query, such as `prefetch_related` / `select_related`
|
||||
* Fix: Responses from the external image URL generator are correctly marked as streaming and will no longer fail when used with Django's cache middleware
|
||||
* Fix: Page copy now works with pages that use multiple inheritance (Jordi Joan)
|
||||
* Fix: Form builder pages now pick up template variables defined in the `get_context` method (Christoph Lipp)
|
||||
* Fix: When copying a page, IDs of child objects within page revision records were not remapped to the new objects; this would cause those objects to be lost from the original page when editing the new one
|
||||
* Fix: Newly added redirects now take effect on all sites, rather than just the site that the Wagtail admin backend was accessed through
|
||||
* Fix: Add user form no longer throws a hard error on validation failure
|
||||
|
||||
|
||||
1.0 (16.07.2015)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@ Contributors
|
|||
* Mitchel Cabuloy
|
||||
* Piet Delport
|
||||
* Tom Christie
|
||||
* Michael van Tellingen
|
||||
* Scot Hacker
|
||||
* Kyungil Choi
|
||||
* Joss Ingram
|
||||
* Christoph Lipp
|
||||
|
||||
|
||||
Translators
|
||||
===========
|
||||
|
|
@ -77,9 +83,11 @@ Translators
|
|||
* German: Karl Sander, Johannes Spielmann, m0rph3u5, pcraston, Tammo van Lessen
|
||||
* Greek: Serafeim Papastefanos, Jim Dal
|
||||
* Hebrew (Israel): bjesus, Lior Abazon
|
||||
* Icelandic: Arnar Tumi Þorsteinsson, saevarom
|
||||
* Italian: Andrea Tagliazucchi, Claudio Bantaloukas, Alessio Di Stasio, Giacomo Ghizzani
|
||||
* Japanese: Daigo Shitara, Toshikazu Michisu
|
||||
* Mongolian: Delgermurun Purevkhuu, miiiga
|
||||
* Norwegian Bokmål: Eirik Krogstad
|
||||
* Polish: Łukasz Bołdys
|
||||
* Portuguese (Brazil): Gilson Filho, Douglas Miranda, Thiago Cangussu, João Luiz Lorencetti, Gladson Brito, Marcelo J. Both
|
||||
* Portuguese (Portugal): Jose Lourenco, Tiago Henriques
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ As standard, Wagtail organises panels into three tabs: 'Content', 'Promote' and
|
|||
FieldPanel('body', classname="full"),
|
||||
]
|
||||
sidebar_content_panels = [
|
||||
SnippetChooserPanel('advert', Advert),
|
||||
SnippetChooserPanel('advert'),
|
||||
InlinePanel('related_links', label="Related links"),
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
===========================
|
||||
Creating multilingual sites
|
||||
===========================
|
||||
===========================================================
|
||||
Creating a multilingual site (by duplicating the page tree)
|
||||
===========================================================
|
||||
|
||||
This tutorial will show you a method of creating multilingual sites in Wagtail.
|
||||
|
||||
Currently, Wagtail doesn't support multiple languages in the same page. The recommended way of creating multilingual websites in Wagtail at the moment is to create one section of your website for each language.
|
||||
This tutorial will show you a method of creating multilingual sites in Wagtail by duplicating the page tree.
|
||||
|
||||
For example::
|
||||
|
||||
211
docs/advanced_topics/i18n/index.rst
Normal file
211
docs/advanced_topics/i18n/index.rst
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
====================
|
||||
Internationalisation
|
||||
====================
|
||||
|
||||
This document describes the internationalisation features of Wagtail and how to create multi-lingual sites.
|
||||
|
||||
Wagtail uses Django's `Internationalisation framework <https://docs.djangoproject.com/en/1.8/topics/i18n/>`_ so most of the steps are the same as other Django projects.
|
||||
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Wagtail admin translations
|
||||
==========================
|
||||
|
||||
The Wagtail admin backend has been translated into many different languages. You can find a list of currently available translations on Wagtail's `Transifex page <https://www.transifex.com/torchbox/wagtail/>`_. (Note: if you're using an old version of Wagtail, this page may not accurately reflect what languages you have available).
|
||||
|
||||
If your language isn't listed on that page, you can easily contribute new languages or correct mistakes. Sign up and submit changes to `Transifex <https://www.transifex.com/torchbox/wagtail/>`_. Translation updates are typically merged into an official release within one month of being submitted.
|
||||
|
||||
|
||||
Changing the primary language of your Wagtail installation
|
||||
==========================================================
|
||||
|
||||
The default language of Wagtail is ``en-us`` (American English). You can change this by tweaking a couple of Django settings:
|
||||
|
||||
- Make sure `USE_I18N <https://docs.djangoproject.com/en/1.8/ref/settings/#use-i18n>`_ is set to ``True``
|
||||
- Set `LANGUAGE_CODE <https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-LANGUAGE_CODE>`_ to your websites' primary language
|
||||
|
||||
If there is a translation available for your language, the Wagtail admin backend should now be in the language you've chosen.
|
||||
|
||||
|
||||
Creating sites with multiple languages
|
||||
======================================
|
||||
|
||||
You can create sites with multiple language support by leveraging Django's `translation features <https://docs.djangoproject.com/en/1.8/topics/i18n/translation/>`_.
|
||||
|
||||
This section of the documentation will show you how to use Django's translation features with Wagtail and also describe a couple of methods for storing/retrieving translated content using Wagtail pages.
|
||||
|
||||
|
||||
Enabling multiple language support
|
||||
----------------------------------
|
||||
|
||||
Firstly, make sure the `USE_I18N <https://docs.djangoproject.com/en/1.8/ref/settings/#use-i18n>`_ Django setting is set to ``True``.
|
||||
|
||||
To enable multi-language support, add ``django.middleware.locale.LocaleMiddleware`` to your ``MIDDLEWARE_CLASSES``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
...
|
||||
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
)
|
||||
|
||||
This middleware class looks at the user's browser language and sets the `language of the site accordingly <https://docs.djangoproject.com/en/1.8/topics/i18n/translation/#how-django-discovers-language-preference>`_.
|
||||
|
||||
|
||||
Serving different languages from different URLs
|
||||
-----------------------------------------------
|
||||
|
||||
Just enabling the multi-language support in Django sometimes may not be enough. By default, Django will serve different languages of the same page with the same URL. This has a couple of drawbacks:
|
||||
|
||||
- Users cannot change language without changing their browser settings
|
||||
- It may not work well with various caching setups (as content varies based on browser settings)
|
||||
|
||||
Django's ``i18n_patterns`` feature, when enabled, prefixes the URLs with the language code (eg ``/en/about-us``). Users are forwarded to their preferred version, based on browser language, when they first visit the site.
|
||||
|
||||
This feature is enabled through the project's root URL configuration. Just put the views you would like to have this enabled for in an ``i18n_patterns`` list and append that to the other URL patterns:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# mysite/urls.py
|
||||
|
||||
from django.conf.urls import include, url
|
||||
from django.conf.urls.i18n import i18n_patterns
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
|
||||
from wagtail.wagtailadmin import urls as wagtailadmin_urls
|
||||
from wagtail.wagtaildocs import urls as wagtaildocs_urls
|
||||
from wagtail.wagtailcore import urls as wagtail_urls
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^django-admin/', include(admin.site.urls)),
|
||||
|
||||
url(r'^admin/', include(wagtailadmin_urls)),
|
||||
url(r'^documents/', include(wagtaildocs_urls)),
|
||||
]
|
||||
|
||||
|
||||
urlpatterns += i18n_patterns('',
|
||||
# These URLs will have /<language_code>/ appended to the beginning
|
||||
|
||||
url(r'^search/$', 'search.views.search', name='search'),
|
||||
|
||||
url(r'', include(wagtail_urls)),
|
||||
)
|
||||
|
||||
You can implement switching between languages by changing the part at the beginning of the URL. As each language has its own URL, it also works well with just about any caching setup.
|
||||
|
||||
|
||||
Translating templates
|
||||
---------------------
|
||||
|
||||
Static text in templates needs to be marked up in a way that allows Django's ``makemessages`` command to find and export the strings for translators and also allow them to switch to translated versions on the when the template is being served.
|
||||
|
||||
As Wagtail uses Django's templates, inserting this markup and the workflow for exporting and translating the strings is the same as any other Django project.
|
||||
|
||||
See: https://docs.djangoproject.com/en/1.8/topics/i18n/translation/#internationalization-in-template-code
|
||||
|
||||
|
||||
Translating content
|
||||
-------------------
|
||||
|
||||
The most common approach for translating content in Wagtail is to duplicate each translatable text field, providing a separate field for each language.
|
||||
|
||||
This section will describe how to implement this method manually but there is a third party module you can use, `wagtail modeltranslation <https://github.com/infoportugal/wagtail-modeltranslation>`_, which may be quicker if it meets your needs.
|
||||
|
||||
|
||||
**Duplicating the fields in your model**
|
||||
|
||||
For each field you would like to be translatable, duplicate it for every language you support and suffix it with the language code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class BlogPage(Page):
|
||||
|
||||
title_fr = models.CharField(max_length=255)
|
||||
|
||||
body_en = StreamField(...)
|
||||
body_fr = StreamField(...)
|
||||
|
||||
# Language-independent fields don't need to be duplicated
|
||||
thumbnail_image = models.ForeignKey('wagtailimages.image', ...)
|
||||
|
||||
.. note::
|
||||
|
||||
We only define the French version of the ``title`` field as Wagtail already provides the English version for us.
|
||||
|
||||
|
||||
**Organising the fields in the admin interface**
|
||||
|
||||
You can either put all the fields with their translations next to each other on the "content" tab or put the translations for other languages on different tabs.
|
||||
|
||||
See :ref:`customising_the_tabbed_interface` for information on how to add more tabs to the admin interface.
|
||||
|
||||
|
||||
**Accessing the fields from the template**
|
||||
|
||||
In order for the translations to be shown on the site frontend, the correct field needs to be used in the template based on what language the client has selected.
|
||||
|
||||
Having to add language checks every time you display a field in a template, could make your templates very messy. Here's a little trick that will allow you to implement this while keeping your templates and model code clean.
|
||||
|
||||
You can use a snippet like the following to add accessor fields on to your page model. These accessor fields will point at the field that contains the language the user has selected.
|
||||
|
||||
Copy this into your project and make sure it's imported in any ``models.py`` files that contain a ``Page`` with translated fields. It will require some modification to support different languages.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from django.utils import translation
|
||||
|
||||
class TranslatedField(object):
|
||||
def __init__(self, en_field, fr_field):
|
||||
self.en_field = en_field
|
||||
self.fr_field = fr_field
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
en = getattr(instance, self.en_field)
|
||||
fr = getattr(instance, self.fr_field)
|
||||
|
||||
if translation.get_language() == 'fr':
|
||||
return fr
|
||||
else:
|
||||
return en
|
||||
|
||||
|
||||
Then, for each translated field, create an instance of ``TranslatedField`` with a nice name (as this is the name your templates will reference).
|
||||
|
||||
For example, here's how we would apply this to the above ``BlogPage`` model:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class BlogPage(Page):
|
||||
...
|
||||
|
||||
translated_title = TranslatedField(
|
||||
'title',
|
||||
'title_fr',
|
||||
)
|
||||
body = TranslatedField(
|
||||
'body_en',
|
||||
'body_fr',
|
||||
)
|
||||
|
||||
|
||||
Finally, in the template, reference the accessors instead of the underlying database fields:
|
||||
|
||||
.. code-block:: html+Django
|
||||
|
||||
{{ self.translated_title }}
|
||||
|
||||
{{ self.body }}
|
||||
|
||||
|
||||
Other approaches
|
||||
----------------
|
||||
|
||||
.. toctree::
|
||||
|
||||
duplicate_tree
|
||||
|
|
@ -8,7 +8,7 @@ Advanced topics
|
|||
settings
|
||||
deploying
|
||||
performance
|
||||
multilingual_sites
|
||||
i18n/index
|
||||
privacy
|
||||
customisation/index
|
||||
third_party_tutorials
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ We recommend using the `Wagtail demo site <https://github.com/torchbox/wagtailde
|
|||
|
||||
Install the wagtaildemo following the instructions in the `wagtaildemo README <https://github.com/torchbox/wagtaildemo/blob/master/README.md>`_, then continue with the instructions below.
|
||||
|
||||
Clone a copy of `the Wagtail codebase <https://github.com/torchbox/wagtail>`_ alongside your demo site at the same level. So in the directory containing wagtaildemo, run::
|
||||
Clone a copy of `the Wagtail codebase <https://github.com/torchbox/wagtail>`_ alongside your demo site at the same level. So in the directory containing the wagtaildemo repo, run::
|
||||
|
||||
git clone https://github.com/torchbox/wagtail.git
|
||||
|
||||
|
|
|
|||
|
|
@ -8,4 +8,3 @@ This section of the guide documents how to perform common tasks as an administra
|
|||
|
||||
managing_users
|
||||
promoted_search_results
|
||||
.. redirects
|
||||
|
|
|
|||
|
|
@ -25,5 +25,5 @@ ___________
|
|||
|
||||
* This interface allows you to select a focal point which can effect how your image displays to visitors on the front-end.
|
||||
* If your images are cropped in some way to make them fit to a specific shape, then the focal point will define the centre point from which the image is cropped.
|
||||
* To set the focal point, simply a marquee around the most important element of the image.
|
||||
* If the feature is set up in your website, then on the front-end you will see the crop of this image focusing on your selection.
|
||||
* To set the focal point, simply drag a marquee around the most important element of the image.
|
||||
* If the feature is set up in your website, then on the front-end you will see the crop of this image focusing on your selection.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ Snippets
|
|||
|
||||
Snippets allow you to create elements on a website once and reuse them in multiple places. Then, if you want to change something on the snippet, you only need to change it once, and it will change across all the occurances of the snippet.
|
||||
|
||||
How snippets are used can vary widely between websites. Here are a few examples of things Torchbox have used snippets for on our clients websites:
|
||||
How snippets are used can vary widely between websites. Here are a few examples of things Torchbox have used snippets for on our clients' websites:
|
||||
|
||||
* For staff contact details, so that they can be added to many pages but managed in one place
|
||||
* For Adverts, either to be applied sitewide or on individual pages
|
||||
|
|
@ -35,4 +35,4 @@ If you are editing a page, and you find yourself in need of a new snippet, do no
|
|||
* You should now see your new snippet, even though you didn't leave the edit page.
|
||||
|
||||
.. Note::
|
||||
Even though this is possible, it is worth saving your page as a draft as often as possible, to avoid your changes being lost by navigating away from the edit page accidentally.
|
||||
Even though this is possible, it is worth saving your page as a draft as often as possible, to avoid your changes being lost by navigating away from the edit page accidentally.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ You can return to the Dashboard at any time by clicking the Wagtail log in the t
|
|||
|
||||
- Clicking the logo returns you to your Dashboard.
|
||||
- The stats at the top of the page describe the total amount of content on the CMS (just for fun!).
|
||||
- The *Pages awaiting moderation* table will only displayed if you have moderator or administrator privileges
|
||||
- The *Pages awaiting moderation* table will only be displayed if you have moderator or administrator privileges
|
||||
|
||||
- Clicking the name of a page will take you to the ‘Edit page’ interface for this page.
|
||||
- Clicking approve or reject will either change the page status to live or return the page to draft status. An email will be sent to the creator of the page giving the result of moderation either way.
|
||||
|
|
@ -23,8 +23,8 @@ You can return to the Dashboard at any time by clicking the Wagtail log in the t
|
|||
|
||||
- The *Your most recent edits* table displays the five pages that you most recently edited.
|
||||
- The date column displays the date that you edited the page. Hover your mouse over the date for a more exact time/date.
|
||||
- The status column displays the current status of the page. A page will have on one of four statuses:
|
||||
- The status column displays the current status of the page. A page will have one of three statuses:
|
||||
|
||||
- Live: Published and accessible to website visitors
|
||||
- Draft: Not live on the website.
|
||||
- Live + Draft: A version of the page is live, but a newer version is in draft mode.
|
||||
- Live + Draft: A version of the page is live, but a newer version is in draft mode.
|
||||
|
|
|
|||
|
|
@ -28,5 +28,5 @@ ________________
|
|||
.. image:: ../../_static/images/screen08.5_reorder_page_handles.png
|
||||
|
||||
* Clicking the icon to the far left of the child pages table will enable the reordering handles. This allows you to reorder the way that content displays in the main menu of your website.
|
||||
* Reorder by dragging the pages by the handles on the far left (the icon made up of 8 dots).
|
||||
* Your new order will be automatically saved each time you drag and drop an item.
|
||||
* Reorder by dragging the pages by the handles on the far left (the icon made up of 6 dots).
|
||||
* Your new order will be automatically saved each time you drag and drop an item.
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ A common feature of Wagtail is the ability to add more than one of a particular
|
|||
|
||||
.. image:: ../../_static/images/screen26_reordering_multiple_items.png
|
||||
|
||||
4. You can reorder your multiple items using the up and down arrows. Doing this will affect the order in which they are display on the live page.
|
||||
* You can reorder your multiple items using the up and down arrows. Doing this will affect the order in which they are display on the live page.
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ The image below demonstrates finding and inserting an image that is already pre
|
|||
|
||||
#. You must include an image title for your uploaded image
|
||||
#. Click the *Choose file* button to choose an image from your computer.
|
||||
#. This *Tags* allows you to associate tags with the image you are uploading. This allows them to be more easily found when searching. Each tag should be separated by a space. Good practice for creating multiple word tags is to use an underscore between each word (e.g. western_yellow_wagtail).
|
||||
#. *Tags* allows you to associate tags with the image you are uploading. This allows them to be more easily found when searching. Each tag should be separated by a space. Good practice for creating multiple word tags is to use an underscore between each word (e.g. western_yellow_wagtail).
|
||||
#. Click *Upload* to insert the uploaded image into the carousel. The image will also be added to the main CMS image library for reuse in other content.
|
||||
|
||||
Inserting images using the rich text field
|
||||
|
|
@ -48,7 +48,7 @@ __________________________________________
|
|||
|
||||
Images can also be inserted into the body text of a page via the rich text editor. When working in a rich text field, click the image illustrated above. You will then be presented with the same options as for inserting images into the main carousel.
|
||||
|
||||
In addition, Wagtail allows you to chose an alignment for you image.
|
||||
In addition, Wagtail allows you to choose an alignment for you image.
|
||||
|
||||
.. image:: ../../_static/images/screen18_image_alignment.png
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ Whichever way you insert a link, you will be presented with the form displayed b
|
|||
* Search for an existing page to link to using the search bar at the top of the pop-up.
|
||||
* Below the search bar you can select the type of link you want to insert. The following types are available:
|
||||
|
||||
* Internal link: A link to an existing page within the RCA website.
|
||||
* Internal link: A link to an existing page within your website.
|
||||
* External link: A link to a page on another website.
|
||||
* Email link: A link that will open the users default email client with the email address prepopulated.
|
||||
* Email link: A link that will open the user's default email client with the email address prepopulated.
|
||||
|
||||
* You can also navigate through the website to find an internal link via the explorer.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ Selecting a page type
|
|||
.. image:: ../../_static/images/screen09_page_type_selection.png
|
||||
|
||||
* On the left of the page chooser screen are listed all the types of pages that you can create. Clicking the page type name will take you to the Create new page screen for that page type (see below).
|
||||
* Clicking the *View all … pages* links on the right will display all the pages that exist on the website of this type. This is to help you judge what type of page you will need to complete your task.
|
||||
* Clicking the *Pages using … Page* links on the right will display all the pages that exist on the website of this type. This is to help you judge what type of page you will need to complete your task.
|
||||
|
||||
.. image:: ../../_static/images/screen10_blank_page_edit_screen.png
|
||||
|
||||
* Once you've selected a page type you will be presented with a blank New page screen.
|
||||
* Click into the areas below each field's heading to start entering content.
|
||||
* Click into the areas below each field's heading to start entering content.
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ FieldRowPanel
|
|||
PageChooserPanel
|
||||
----------------
|
||||
|
||||
.. class:: PageChooserPanel(field_name, model=None)
|
||||
.. class:: PageChooserPanel(field_name, page_type=None)
|
||||
|
||||
You can explicitly link :class:`~wagtail.wagtailcore.models.Page`-derived models together using the :class:`~wagtail.wagtailcore.models.Page` model and ``PageChooserPanel``.
|
||||
|
||||
|
|
@ -166,7 +166,9 @@ PageChooserPanel
|
|||
PageChooserPanel('related_page', 'demo.PublisherPage'),
|
||||
]
|
||||
|
||||
``PageChooserPanel`` takes two arguments: a field name and an optional page type. Specifying a page type (in the form of an ``"appname.modelname"`` string) will filter the chooser to display only pages of that type.
|
||||
``PageChooserPanel`` takes two arguments: a field name and an optional page type. Specifying a page type (in the form of an ``"appname.modelname"`` string) will filter the chooser to display only pages of that type. A list or tuple of page types can also be passed in, to allow choosing a page that matches any of those page types::
|
||||
|
||||
PageChooserPanel('related_page', ['demo.PublisherPage', 'demo.AuthorPage'])
|
||||
|
||||
ImageChooserPanel
|
||||
-----------------
|
||||
|
|
@ -231,9 +233,13 @@ DocumentChooserPanel
|
|||
SnippetChooserPanel
|
||||
-------------------
|
||||
|
||||
.. class:: wagtail.wagtailsnippets.edit_handlers.SnippetChooserPanel(field_name, model)
|
||||
.. versionchanged:: 1.1
|
||||
|
||||
Snippets are vanilla Django models you create yourself without a Wagtail-provided base class. So using them as a field in a page requires specifying your own ``appname.modelname``. A chooser, ``SnippetChooserPanel``, is provided which takes the field name and snippet class.
|
||||
Before Wagtail 1.1, it was necessary to pass the snippet model class as a second parameter to ``SnippetChooserPanel``. This is now automatically picked up from the field.
|
||||
|
||||
.. class:: wagtail.wagtailsnippets.edit_handlers.SnippetChooserPanel(field_name, snippet_type=None)
|
||||
|
||||
Snippets are vanilla Django models you create yourself without a Wagtail-provided base class. A chooser, ``SnippetChooserPanel``, is provided which takes the field name as an argument.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
|
@ -249,7 +255,7 @@ SnippetChooserPanel
|
|||
)
|
||||
|
||||
content_panels = Page.content_panels + [
|
||||
SnippetChooserPanel('advert', Advert),
|
||||
SnippetChooserPanel('advert'),
|
||||
]
|
||||
|
||||
See :ref:`snippets` for more information.
|
||||
|
|
|
|||
|
|
@ -155,11 +155,11 @@ Using an example from the Wagtail demo site, here's what the tag model and the r
|
|||
|
||||
from modelcluster.fields import ParentalKey
|
||||
from modelcluster.contrib.taggit import ClusterTaggableManager
|
||||
from taggit.models import Tag, TaggedItemBase
|
||||
...
|
||||
from taggit.models import TaggedItemBase
|
||||
|
||||
class BlogPageTag(TaggedItemBase):
|
||||
content_object = ParentalKey('demo.BlogPage', related_name='tagged_items')
|
||||
...
|
||||
|
||||
class BlogPage(Page):
|
||||
...
|
||||
tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
|
||||
|
|
|
|||
|
|
@ -153,6 +153,10 @@ In addition to the model fields provided, ``Page`` has many properties and metho
|
|||
|
||||
Defines which template file should be used to render the login form for Protected pages using this model. This overrides the default, defined using ``PASSWORD_REQUIRED_TEMPLATE`` in your settings. See :ref:`private_pages`
|
||||
|
||||
.. attribute:: is_creatable
|
||||
|
||||
Controls if this page can be created through the Wagtail administration. Defaults to True, and is not inherited by subclasses. This is useful when using `multi-table inheritance <https://docs.djangoproject.com/en/1.8/topics/db/models/#multi-table-inheritance>`_, to stop the base model from being created as an actual page.
|
||||
|
||||
``Site``
|
||||
========
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,28 @@ Atomic rebuilding of Elasticsearch indexes
|
|||
|
||||
The Elasticsearch search backend now accepts an experimental ``ATOMIC_REBUILD`` flag which ensures that the existing search index continues to be available while the ``update_index`` task is running. See :ref:`wagtailsearch_backends_atomic_rebuild`.
|
||||
|
||||
Permissions fixes in the admin interface
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A number of inconsistencies around permissions in the admin interface were fixed in this release:
|
||||
|
||||
* Removed all permissions for "User profile" (not used)
|
||||
* Removed "delete" permission for Images and documents (not used)
|
||||
* Users can now access images and documents when they only have the "change" permission (previously required "add" permission as well)
|
||||
* Permissions for Users now taken from custom user model, if set (previously always used permissions on Djangos builtin User model)
|
||||
* Groups and Users now respond consistently to their respective "add", "change" and "delete" permissions
|
||||
|
||||
Searchable snippets
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Snippets that inherit from ``wagtail.wagtailsearch.index.Indexed`` are now given a search box on the snippet chooser and listing pages. See :ref:`wagtailsnippets_making_snippets_searchable`.
|
||||
|
||||
|
||||
Minor features
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
* The :mod:`~wagtail.contrib.wagtailapi` module has been refactored to use Django REST Framework
|
||||
* Implemented deletion of form submissions
|
||||
* Implemented pagination in the page chooser modal
|
||||
* Changed INSTALLED_APPS in project template to list apps in precedence order
|
||||
* The ``{% image %}`` tag now supports filters on the image variable, e.g. ``{% image primary_img|default:secondary_img width-500 %}``
|
||||
|
|
@ -39,8 +57,19 @@ Minor features
|
|||
* Added optional directory argument to "wagtail start" command
|
||||
* Non-superusers can now view/edit/delete sites if they have the correct permissions
|
||||
* Image file size is now stored in the database, to avoid unnecessary filesystem lookups
|
||||
* Page URL lookups hit the cache/database less often
|
||||
* Updated URLs within the admin backend to use namespaces
|
||||
* The ``update_index`` task now indexes objects in batches of 1000, to indicate progress and avoid excessive memory use
|
||||
* Added database indexes on PageRevision and Image to improve performance on large sites
|
||||
* Search in page chooser now uses Wagtail's search framework, to order results by relevance
|
||||
* ``PageChooserPanel`` now supports passing a list (or tuple) of accepted page types
|
||||
* The snippet type parameter of ``SnippetChooserPanel`` can now be omitted, or passed as a model name string rather than a model class
|
||||
* Added aliases for the ``self`` template variable to accommodate Jinja as a templating engine: ``page`` for pages, ``field_panel`` for field panels / edit handlers, and ``value`` for blocks
|
||||
* Added signposting text to the explorer to steer editors away from creating pages at the root level unless they are setting up new sites
|
||||
* "Clear choice" and "Edit this page" buttons are no longer shown on the page field of the group page permissions form
|
||||
* Altered styling of stream controls to be more like all other buttons
|
||||
* Added ability to mark page models as not available for creation using the flag ``is_creatable``; pages that are abstract Django models are automatically made non-creatable
|
||||
* New translations for Norwegian Bokmål and Icelandic
|
||||
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
|
@ -48,6 +77,17 @@ Bug fixes
|
|||
* Text areas in the non-default tab of the page editor now resize to the correct height
|
||||
* Tabs in "insert link" modal in the rich text editor no longer disappear (Tim Heap)
|
||||
* H2 elements in rich text fields were accidentally given a click() binding when put insite a collapsible multi field panel
|
||||
* The ``wagtailimages`` module is now compatible with remote storage backends that do not allow reopening closed files
|
||||
* Search no longer crashes when auto-indexing a model that doesn't have an ``id`` field
|
||||
* The ``wagtailfrontendcache`` module's HTTP backend has been rewritten to reliably direct requests to the configured cache hostname
|
||||
* Resizing single pixel images with the "fill" filter no longer raises "ZeroDivisionError" or "tile cannot extend outside image"
|
||||
* The queryset returned from ``search`` operations when using the database search backend now correctly preserves additional properties of the original query, such as ``prefetch_related`` / ``select_related``
|
||||
* Responses from the external image URL generator are correctly marked as streaming and will no longer fail when used with Django's cache middleware
|
||||
* Page copy now works with pages that use multiple inheritance
|
||||
* Form builder pages now pick up template variables defined in the ``get_context`` method
|
||||
* When copying a page, IDs of child objects within page revision records were not remapped to the new objects; this would cause those objects to be lost from the original page when editing the new one
|
||||
* Newly added redirects now take effect on all sites, rather than just the site that the Wagtail admin backend was accessed through
|
||||
* Add user form no longer throws a hard error on validation failure
|
||||
|
||||
|
||||
Upgrade considerations
|
||||
|
|
@ -68,3 +108,19 @@ To re-enable it, add :mod:`wagtail.contrib.wagtailsearchpromotions` to your ``IN
|
|||
'wagtail.contrib.wagtailsearchpromotions',
|
||||
|
||||
...
|
||||
|
||||
If you have references to the ``wagtail.wagtailsearch.models.EditorsPick`` model in your
|
||||
project, you will need to update these to point to the :mod:`wagtail.contrib.wagtailsearchpromotions.models.SearchPromotion` model instead.
|
||||
|
||||
If you created your project using the ``wagtail start`` command with Wagtail 1.0,
|
||||
you will probably have references to this model in the ``search/views.py`` file.
|
||||
|
||||
|
||||
``is_abstract`` flag on page models has been replaced by ``is_creatable``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Previous versions of Wagtail provided an undocumented ``is_abstract`` flag on page models - not to be confused with Django's ``abstract`` Meta flag - to indicate that it should not be included in the list of available page types for creation. (Typically this would be used on model classes that were designed to be subclassed to create new page types, rather than used directly.) To avoid confusion with Django's distinct concept of abstract models, this has now been replaced by a new flag, ``is_creatable``.
|
||||
|
||||
If you have used ``is_abstract = True`` on any of your models, you should now change this to ``is_creatable = False``.
|
||||
|
||||
It is not necessary to include this flag if the model is abstract in the Django sense (i.e. it has ``abstract = True`` in the model's ``Meta`` class), since it would never be valid to create pages of that type.
|
||||
|
|
|
|||
18
docs/releases/1.2.rst
Normal file
18
docs/releases/1.2.rst
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
==========================================
|
||||
Wagtail 1.2 release notes - IN DEVELOPMENT
|
||||
==========================================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
What's new
|
||||
==========
|
||||
|
||||
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
||||
* Deleting a page permission from the groups admin UI does not immediately submit the form
|
||||
|
||||
|
|
@ -4,6 +4,7 @@ Release notes
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
1.2
|
||||
1.1
|
||||
1.0
|
||||
0.8.8
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Snippets
|
|||
|
||||
Snippets are pieces of content which do not necessitate a full webpage to render. They could be used for making secondary content, such as headers, footers, and sidebars, editable in the Wagtail admin. Snippets are models which do not inherit the ``Page`` class and are thus not organized into the Wagtail tree, but can still be made editable by assigning panels and identifying the model as a snippet with the ``register_snippet`` class decorator.
|
||||
|
||||
Snippets are not search-able or order-able in the Wagtail admin, so decide carefully if the content type you would want to build into a snippet might be more suited to a page.
|
||||
Snippets lack many of the features of pages, such as being orderable in the Wagtail admin or having a defined URL, so decide carefully if the content type you would want to build into a snippet might be more suited to a page.
|
||||
|
||||
Snippet Models
|
||||
--------------
|
||||
|
|
@ -24,20 +24,20 @@ Here's an example snippet from the Wagtail demo website:
|
|||
|
||||
@register_snippet
|
||||
class Advert(models.Model):
|
||||
url = models.URLField(null=True, blank=True)
|
||||
text = models.CharField(max_length=255)
|
||||
|
||||
panels = [
|
||||
FieldPanel('url'),
|
||||
FieldPanel('text'),
|
||||
]
|
||||
|
||||
def __unicode__(self):
|
||||
return self.text
|
||||
url = models.URLField(null=True, blank=True)
|
||||
text = models.CharField(max_length=255)
|
||||
|
||||
panels = [
|
||||
FieldPanel('url'),
|
||||
FieldPanel('text'),
|
||||
]
|
||||
|
||||
def __str__(self): # __unicode__ on Python 2
|
||||
return self.text
|
||||
|
||||
The ``Advert`` model uses the basic Django model class and defines two properties: text and URL. The editing interface is very close to that provided for ``Page``-derived models, with fields assigned in the panels property. Snippets do not use multiple tabs of fields, nor do they provide the "save as draft" or "submit for moderation" features.
|
||||
|
||||
``@register_snippet`` tells Wagtail to treat the model as a snippet. The ``panels`` list defines the fields to show on the snippet editing page. It's also important to provide a string representation of the class through ``def __unicode__(self):`` so that the snippet objects make sense when listed in the Wagtail admin.
|
||||
``@register_snippet`` tells Wagtail to treat the model as a snippet. The ``panels`` list defines the fields to show on the snippet editing page. It's also important to provide a string representation of the class through ``def __str__(self):`` so that the snippet objects make sense when listed in the Wagtail admin.
|
||||
|
||||
Including Snippets in Template Tags
|
||||
-----------------------------------
|
||||
|
|
@ -60,10 +60,10 @@ First, add a new python file to a ``templatetags`` folder within your app. The d
|
|||
# Advert snippets
|
||||
@register.inclusion_tag('demo/tags/adverts.html', takes_context=True)
|
||||
def adverts(context):
|
||||
return {
|
||||
'adverts': Advert.objects.all(),
|
||||
'request': context['request'],
|
||||
}
|
||||
return {
|
||||
'adverts': Advert.objects.all(),
|
||||
'request': context['request'],
|
||||
}
|
||||
|
||||
``@register.inclusion_tag()`` takes two variables: a template and a boolean on whether that template should be passed a request context. It's a good idea to include request contexts in your custom template tags, since some Wagtail-specific template tags like ``pageurl`` need the context to work properly. The template tag function could take arguments and filter the adverts to return a specific model, but for brevity we'll just use ``Advert.objects.all()``.
|
||||
|
||||
|
|
@ -102,17 +102,18 @@ In the above example, the list of adverts is a fixed list, displayed as part of
|
|||
from wagtail.wagtailsnippets.edit_handlers import SnippetChooserPanel
|
||||
# ...
|
||||
class BookPage(Page):
|
||||
advert = models.ForeignKey(
|
||||
'demo.Advert',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
advert = models.ForeignKey(
|
||||
'demo.Advert',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+'
|
||||
)
|
||||
|
||||
|
||||
BookPage.content_panels = [
|
||||
SnippetChooserPanel('advert', Advert),
|
||||
# ...
|
||||
SnippetChooserPanel('advert'),
|
||||
# ...
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -133,29 +134,32 @@ To attach multiple adverts to a page, the ``SnippetChooserPanel`` can be placed
|
|||
...
|
||||
|
||||
class BookPageAdvertPlacement(Orderable, models.Model):
|
||||
page = ParentalKey('demo.BookPage', related_name='advert_placements')
|
||||
advert = models.ForeignKey('demo.Advert', related_name='+')
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Advert Placement"
|
||||
verbose_name_plural = "Advert Placements"
|
||||
|
||||
panels = [
|
||||
SnippetChooserPanel('advert', Advert),
|
||||
]
|
||||
|
||||
def __unicode__(self):
|
||||
return self.page.title + " -> " + self.advert.text
|
||||
|
||||
page = ParentalKey('demo.BookPage', related_name='advert_placements')
|
||||
advert = models.ForeignKey('demo.Advert', related_name='+')
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Advert Placement"
|
||||
verbose_name_plural = "Advert Placements"
|
||||
|
||||
panels = [
|
||||
SnippetChooserPanel('advert'),
|
||||
]
|
||||
|
||||
def __str__(self): # __unicode__ on Python 2
|
||||
return self.page.title + " -> " + self.advert.text
|
||||
|
||||
|
||||
class BookPage(Page):
|
||||
...
|
||||
|
||||
...
|
||||
|
||||
|
||||
BookPage.content_panels = [
|
||||
InlinePanel('advert_placements', label="Adverts"),
|
||||
# ...
|
||||
InlinePanel('advert_placements', label="Adverts"),
|
||||
# ...
|
||||
]
|
||||
|
||||
|
||||
|
||||
These child objects are now accessible through the page's ``advert_placements`` property, and from there we can access the linked Advert snippet as ``advert``. In the template for ``BookPage``, we could include the following:
|
||||
|
||||
.. code-block:: django
|
||||
|
|
@ -165,3 +169,58 @@ These child objects are now accessible through the page's ``advert_placements``
|
|||
{% endfor %}
|
||||
|
||||
|
||||
.. _wagtailsnippets_making_snippets_searchable:
|
||||
|
||||
Making Snippets Searchable
|
||||
--------------------------
|
||||
|
||||
If a snippet model inherits from ``wagtail.wagtailsearch.index.Indexed``, as described in :ref:`wagtailsearch_indexing_models`, Wagtail will automatically add a search box to the chooser interface for that snippet type. For example, the ``Advert`` snippet could be made searchable as follows:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
...
|
||||
|
||||
from wagtail.wagtailsearch import index
|
||||
|
||||
...
|
||||
|
||||
@register_snippet
|
||||
class Advert(models.Model, index.Indexed):
|
||||
url = models.URLField(null=True, blank=True)
|
||||
text = models.CharField(max_length=255)
|
||||
|
||||
panels = [
|
||||
FieldPanel('url'),
|
||||
FieldPanel('text'),
|
||||
]
|
||||
|
||||
search_fields = [
|
||||
index.SearchField('text', partial_match=True),
|
||||
]
|
||||
|
||||
|
||||
Tagging snippets
|
||||
----------------
|
||||
|
||||
Adding tags to snippets is very similar to adding tags to pages. The only difference is that :class:`taggit.manager.TaggableManager` should be used in the place of :class:`~modelcluster.contrib.taggit.ClusterTaggableManager`.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from modelcluster.fields import ParentalKey
|
||||
from taggit.models import TaggedItemBase
|
||||
from taggit.managers import TaggableManager
|
||||
|
||||
class AdvertTag(TaggedItemBase):
|
||||
content_object = ParentalKey('demo.Advert', related_name='tagged_items')
|
||||
|
||||
@register_snippet
|
||||
class Advert(models.Model):
|
||||
...
|
||||
tags = TaggableManager(through=BlogPageTag, blank=True)
|
||||
|
||||
panels = [
|
||||
...
|
||||
FieldPanel('tags'),
|
||||
]
|
||||
|
||||
The :ref:`documentation on tagging pages <tagging>` has more information on how to use tags in views.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ tx pull -a --minimum-perc=30
|
|||
# These things are only needed by translators (which they won't be seen by) and make the translation updates difficult to check
|
||||
find ../wagtail -iname *.po ! -iwholename */en/* -exec msgattrib --translated --no-fuzzy --no-obsolete --no-location -o {} {} \;
|
||||
|
||||
# Run makemessages on each app
|
||||
# Run compilemessages on each app
|
||||
for d in $(find ../wagtail -iname *.po | sed 's|\(.*\)/locale.*|\1|' | sort -u);
|
||||
do
|
||||
pushd $d
|
||||
|
|
|
|||
10
scripts/rebuild-translation-sources.sh
Executable file
10
scripts/rebuild-translation-sources.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
# Delete old translation sources
|
||||
find ../wagtail -iname *.po -iwholename */en/* -delete
|
||||
|
||||
# Run makemessages on each app
|
||||
for d in $(find ../wagtail -iwholename */locale/* | sed 's|\(.*\)/locale.*|\1|' | sort -u);
|
||||
do
|
||||
pushd $d
|
||||
django-admin makemessages --locale=en
|
||||
popd
|
||||
done
|
||||
3
setup.py
3
setup.py
|
|
@ -28,12 +28,11 @@ install_requires = [
|
|||
"django-modelcluster>=0.6",
|
||||
"django-taggit>=0.13.0",
|
||||
"django-treebeard==3.0",
|
||||
"djangorestframework==3.1.3",
|
||||
"djangorestframework>=3.1.3",
|
||||
"Pillow>=2.6.1",
|
||||
"beautifulsoup4>=4.3.2",
|
||||
"html5lib==0.999",
|
||||
"Unidecode>=0.04.14",
|
||||
'requests>=2.0.0',
|
||||
"Willow==0.2.1",
|
||||
]
|
||||
|
||||
|
|
|
|||
1
tox.ini
1
tox.ini
|
|
@ -28,7 +28,6 @@ deps =
|
|||
html5lib==0.999
|
||||
Unidecode>=0.04.14
|
||||
six==1.7.3
|
||||
requests==2.3.0
|
||||
elasticsearch==1.1.0
|
||||
mock==1.0.1
|
||||
python-dateutil==2.2
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.http import Http404
|
||||
|
||||
|
|
@ -18,14 +20,14 @@ from .filters import (
|
|||
)
|
||||
from .renderers import WagtailJSONRenderer
|
||||
from .pagination import WagtailPagination
|
||||
from .serializers import WagtailSerializer, PageSerializer, DocumentSerializer
|
||||
from .serializers import BaseSerializer, PageSerializer, DocumentSerializer, ImageSerializer, get_serializer_class
|
||||
from .utils import BadRequestError
|
||||
|
||||
|
||||
class BaseAPIEndpoint(GenericViewSet):
|
||||
renderer_classes = [WagtailJSONRenderer]
|
||||
pagination_class = WagtailPagination
|
||||
serializer_class = WagtailSerializer
|
||||
base_serializer_class = BaseSerializer
|
||||
filter_classes = []
|
||||
queryset = None # Set on subclasses or implement `get_queryset()`.
|
||||
|
||||
|
|
@ -85,28 +87,61 @@ class BaseAPIEndpoint(GenericViewSet):
|
|||
if unknown_parameters:
|
||||
raise BadRequestError("query parameter is not an operation or a recognised field: %s" % ', '.join(sorted(unknown_parameters)))
|
||||
|
||||
def get_serializer_context(self):
|
||||
"""
|
||||
The serialization context differs between listing and detail views.
|
||||
"""
|
||||
def get_serializer_class(self):
|
||||
request = self.request
|
||||
if self.action == 'listing_view':
|
||||
|
||||
# Get model
|
||||
if self.action == 'listing_view':
|
||||
model = self.get_queryset().model
|
||||
else:
|
||||
model = type(self.get_object())
|
||||
|
||||
# Get all available fields
|
||||
all_fields = self.get_api_fields(model)
|
||||
all_fields = list(OrderedDict.fromkeys(all_fields)) # Removes any duplicates in case the developer put "title" in api_fields
|
||||
|
||||
if self.action == 'listing_view':
|
||||
# Listing views just show the title field and any other allowed field the user specified
|
||||
if 'fields' in request.GET:
|
||||
fields = set(request.GET['fields'].split(','))
|
||||
else:
|
||||
fields = {'title'}
|
||||
|
||||
unknown_fields = fields - set(all_fields)
|
||||
|
||||
if unknown_fields:
|
||||
raise BadRequestError("unknown fields: %s" % ', '.join(sorted(unknown_fields)))
|
||||
|
||||
# Reorder fields so it matches the order of all_fields
|
||||
fields = [field for field in all_fields if field in fields]
|
||||
else:
|
||||
# Detail views show all fields all the time
|
||||
fields = all_fields
|
||||
|
||||
# Always show id and meta first
|
||||
fields = ['id', 'meta'] + fields
|
||||
|
||||
# If showing details, add the parent field
|
||||
if isinstance(self, PagesAPIEndpoint) and self.get_serializer_context().get('show_details', False):
|
||||
fields.insert(2, 'parent')
|
||||
|
||||
return get_serializer_class(model, fields, base=self.base_serializer_class)
|
||||
|
||||
def get_serializer_context(self):
|
||||
"""
|
||||
The serialization context differs between listing and detail views.
|
||||
"""
|
||||
request = self.request
|
||||
|
||||
if self.action == 'listing_view':
|
||||
return {
|
||||
'request': request,
|
||||
'view': self,
|
||||
'fields': fields
|
||||
}
|
||||
|
||||
return {
|
||||
'request': request,
|
||||
'view': self,
|
||||
'all_fields': True,
|
||||
'show_details': True
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +170,7 @@ class BaseAPIEndpoint(GenericViewSet):
|
|||
|
||||
|
||||
class PagesAPIEndpoint(BaseAPIEndpoint):
|
||||
serializer_class = PageSerializer
|
||||
base_serializer_class = PageSerializer
|
||||
filter_backends = [
|
||||
FieldsFilter,
|
||||
ChildOfFilter,
|
||||
|
|
@ -185,6 +220,7 @@ class PagesAPIEndpoint(BaseAPIEndpoint):
|
|||
|
||||
class ImagesAPIEndpoint(BaseAPIEndpoint):
|
||||
queryset = get_image_model().objects.all().order_by('id')
|
||||
base_serializer_class = ImageSerializer
|
||||
filter_backends = [FieldsFilter, OrderingFilter, SearchFilter]
|
||||
extra_api_fields = ['title', 'tags', 'width', 'height']
|
||||
name = 'images'
|
||||
|
|
@ -196,7 +232,7 @@ class ImagesAPIEndpoint(BaseAPIEndpoint):
|
|||
|
||||
class DocumentsAPIEndpoint(BaseAPIEndpoint):
|
||||
queryset = Document.objects.all().order_by('id')
|
||||
serializer_class = DocumentSerializer
|
||||
base_serializer_class = DocumentSerializer
|
||||
filter_backends = [FieldsFilter, OrderingFilter, SearchFilter]
|
||||
extra_api_fields = ['title', 'tags']
|
||||
name = 'documents'
|
||||
|
|
|
|||
|
|
@ -6,11 +6,6 @@ from django.utils.six import text_type
|
|||
|
||||
from rest_framework import renderers
|
||||
|
||||
from taggit.managers import _TaggableManager
|
||||
from taggit.models import Tag
|
||||
|
||||
from wagtail.wagtailcore.blocks import StreamValue
|
||||
|
||||
from .utils import URLPath, ObjectDetailURL, get_base_url
|
||||
|
||||
|
||||
|
|
@ -35,11 +30,7 @@ class WagtailJSONRenderer(renderers.BaseRenderer):
|
|||
|
||||
class WagtailAPIJSONEncoder(DjangoJSONEncoder):
|
||||
def default(self, o):
|
||||
if isinstance(o, _TaggableManager):
|
||||
return list(o.all())
|
||||
elif isinstance(o, Tag):
|
||||
return o.name
|
||||
elif isinstance(o, URLPath):
|
||||
if isinstance(o, URLPath):
|
||||
return get_full_url(request, o.path)
|
||||
elif isinstance(o, ObjectDetailURL):
|
||||
detail_view = find_model_detail_view(o.model, endpoints)
|
||||
|
|
@ -48,8 +39,6 @@ class WagtailJSONRenderer(renderers.BaseRenderer):
|
|||
return get_full_url(request, reverse(detail_view, args=(o.pk, )))
|
||||
else:
|
||||
return None
|
||||
elif isinstance(o, StreamValue):
|
||||
return o.stream_block.get_prep_value(o)
|
||||
else:
|
||||
return super(WagtailAPIJSONEncoder, self).default(o)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,171 +2,282 @@ from __future__ import absolute_import
|
|||
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.db import models
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from modelcluster.models import get_all_child_relations
|
||||
|
||||
from rest_framework.serializers import BaseSerializer
|
||||
from taggit.managers import _TaggableManager
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.fields import Field
|
||||
from rest_framework import relations
|
||||
|
||||
from wagtail.utils.compat import get_related_model
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailcore import fields as wagtailcore_fields
|
||||
|
||||
from .utils import ObjectDetailURL, URLPath, BadRequestError, pages_for_site
|
||||
from .utils import ObjectDetailURL, URLPath, pages_for_site
|
||||
|
||||
|
||||
def get_api_data(obj, fields):
|
||||
# Find any child relations (pages only)
|
||||
child_relations = {}
|
||||
if isinstance(obj, Page):
|
||||
child_relations = {
|
||||
child_relation.field.rel.related_name: get_related_model(child_relation)
|
||||
for child_relation in get_all_child_relations(type(obj))
|
||||
}
|
||||
class MetaField(Field):
|
||||
"""
|
||||
Serializes the "meta" section of each object.
|
||||
|
||||
# Loop through fields
|
||||
for field_name in fields:
|
||||
# Check child relations
|
||||
if field_name in child_relations and hasattr(child_relations[field_name], 'api_fields'):
|
||||
yield field_name, [
|
||||
dict(get_api_data(child_object, child_relations[field_name].api_fields))
|
||||
for child_object in getattr(obj, field_name).all()
|
||||
]
|
||||
continue
|
||||
This section is used for storing non-field data such as model name, urls, etc.
|
||||
|
||||
# Check django fields
|
||||
try:
|
||||
field = obj._meta.get_field(field_name)
|
||||
Example:
|
||||
|
||||
if field.rel and isinstance(field.rel, models.ManyToOneRel):
|
||||
# Foreign key
|
||||
val = field._get_val_from_obj(obj)
|
||||
"meta": {
|
||||
"type": "wagtailimages.Image",
|
||||
"detail_url": "http://api.example.com/v1/images/1/"
|
||||
}
|
||||
"""
|
||||
def get_attribute(self, instance):
|
||||
return instance
|
||||
|
||||
if val:
|
||||
yield field_name, OrderedDict([
|
||||
('id', field._get_val_from_obj(obj)),
|
||||
('meta', OrderedDict([
|
||||
('type', field.rel.to._meta.app_label + '.' + field.rel.to.__name__),
|
||||
('detail_url', ObjectDetailURL(field.rel.to, val)),
|
||||
])),
|
||||
])
|
||||
else:
|
||||
yield field_name, None
|
||||
else:
|
||||
yield field_name, field._get_val_from_obj(obj)
|
||||
|
||||
continue
|
||||
except models.fields.FieldDoesNotExist:
|
||||
pass
|
||||
|
||||
# Check attributes
|
||||
if hasattr(obj, field_name):
|
||||
value = getattr(obj, field_name)
|
||||
yield field_name, force_text(value, strings_only=True)
|
||||
continue
|
||||
def to_representation(self, obj):
|
||||
return OrderedDict([
|
||||
('type', type(obj)._meta.app_label + '.' + type(obj).__name__),
|
||||
('detail_url', ObjectDetailURL(type(obj), obj.pk)),
|
||||
])
|
||||
|
||||
|
||||
class WagtailSerializer(BaseSerializer):
|
||||
def to_representation(self, instance):
|
||||
request = self.context['request']
|
||||
fields = self.context.get('fields', frozenset())
|
||||
all_fields = self.context.get('all_fields', False)
|
||||
show_details = self.context.get('show_details', False)
|
||||
return self.serialize_object(
|
||||
request,
|
||||
instance,
|
||||
fields=fields,
|
||||
all_fields=all_fields,
|
||||
show_details=show_details
|
||||
)
|
||||
class PageMetaField(MetaField):
|
||||
"""
|
||||
A subclass of MetaField for Page objects.
|
||||
|
||||
def serialize_object_metadata(self, request, obj, show_details=False):
|
||||
"""
|
||||
This returns a JSON-serialisable dict to use for the "meta"
|
||||
section of a particlular object.
|
||||
"""
|
||||
data = OrderedDict()
|
||||
Changes the "type" field to use the name of the specific model of the page.
|
||||
|
||||
# Add type
|
||||
data['type'] = type(obj)._meta.app_label + '.' + type(obj).__name__
|
||||
data['detail_url'] = ObjectDetailURL(type(obj), obj.pk)
|
||||
Example:
|
||||
|
||||
return data
|
||||
|
||||
def serialize_object(self, request, obj, fields=frozenset(), extra_data=(), all_fields=False, show_details=False):
|
||||
"""
|
||||
This converts an object into JSON-serialisable dict so it can
|
||||
be used in the API.
|
||||
"""
|
||||
data = [
|
||||
('id', obj.id),
|
||||
]
|
||||
|
||||
# Add meta
|
||||
metadata = self.serialize_object_metadata(request, obj, show_details=show_details)
|
||||
if metadata:
|
||||
data.append(('meta', metadata))
|
||||
|
||||
# Add extra data
|
||||
data.extend(extra_data)
|
||||
|
||||
# Add other fields
|
||||
api_fields = self.context['view'].get_api_fields(type(obj))
|
||||
api_fields = list(OrderedDict.fromkeys(api_fields)) # Removes any duplicates in case the user put "title" in api_fields
|
||||
|
||||
if all_fields:
|
||||
fields = api_fields
|
||||
else:
|
||||
unknown_fields = fields - set(api_fields)
|
||||
|
||||
if unknown_fields:
|
||||
raise BadRequestError("unknown fields: %s" % ', '.join(sorted(unknown_fields)))
|
||||
|
||||
# Reorder fields so it matches the order of api_fields
|
||||
fields = [field for field in api_fields if field in fields]
|
||||
|
||||
data.extend(get_api_data(obj, fields))
|
||||
|
||||
return OrderedDict(data)
|
||||
"meta": {
|
||||
"type": "blog.BlogPage",
|
||||
"detail_url": "http://api.example.com/v1/pages/1/"
|
||||
}
|
||||
"""
|
||||
def to_representation(self, page):
|
||||
return OrderedDict([
|
||||
('type', page.specific_class._meta.app_label + '.' + page.specific_class.__name__),
|
||||
('detail_url', ObjectDetailURL(type(page), page.pk)),
|
||||
])
|
||||
|
||||
|
||||
class PageSerializer(WagtailSerializer):
|
||||
def serialize_object_metadata(self, request, page, show_details=False):
|
||||
data = super(PageSerializer, self).serialize_object_metadata(request, page, show_details=show_details)
|
||||
class DocumentMetaField(MetaField):
|
||||
"""
|
||||
A subclass of MetaField for Document objects.
|
||||
|
||||
# Add type
|
||||
data['type'] = page.specific_class._meta.app_label + '.' + page.specific_class.__name__
|
||||
Adds a "download_url" field.
|
||||
|
||||
return data
|
||||
"meta": {
|
||||
"type": "wagtaildocs.Document",
|
||||
"detail_url": "http://api.example.com/v1/documents/1/",
|
||||
"download_url": "http://api.example.com/documents/1/my_document.pdf"
|
||||
}
|
||||
"""
|
||||
def to_representation(self, document):
|
||||
data = OrderedDict([
|
||||
('type', "wagtaildocs.Document"),
|
||||
('detail_url', ObjectDetailURL(type(document), document.pk)),
|
||||
])
|
||||
|
||||
def serialize_object(self, request, page, fields=frozenset(), extra_data=(), all_fields=False, show_details=False):
|
||||
# Add parent
|
||||
if show_details:
|
||||
parent = page.get_parent()
|
||||
|
||||
site_pages = pages_for_site(request.site)
|
||||
if site_pages.filter(id=parent.id).exists():
|
||||
parent_class = parent.specific_class
|
||||
|
||||
extra_data += (
|
||||
('parent', OrderedDict([
|
||||
('id', parent.id),
|
||||
('meta', OrderedDict([
|
||||
('type', parent_class._meta.app_label + '.' + parent_class.__name__),
|
||||
('detail_url', ObjectDetailURL(parent_class, parent.id)),
|
||||
])),
|
||||
])),
|
||||
)
|
||||
|
||||
return super(PageSerializer, self).serialize_object(request, page, fields=fields, extra_data=extra_data, all_fields=all_fields, show_details=show_details)
|
||||
|
||||
|
||||
class DocumentSerializer(WagtailSerializer):
|
||||
def serialize_object_metadata(self, request, document, show_details=False):
|
||||
data = super(DocumentSerializer, self).serialize_object_metadata(request, document, show_details=show_details)
|
||||
|
||||
# Download URL
|
||||
if show_details:
|
||||
# Add download url
|
||||
if self.context.get('show_details', False):
|
||||
data['download_url'] = URLPath(document.url)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
class RelatedField(relations.RelatedField):
|
||||
"""
|
||||
Serializes related objects (eg, foreign keys).
|
||||
|
||||
Example:
|
||||
|
||||
"feed_image": {
|
||||
"id": 1,
|
||||
"meta": {
|
||||
"type": "wagtailimages.Image",
|
||||
"detail_url": "http://api.example.com/v1/images/1/"
|
||||
}
|
||||
}
|
||||
"""
|
||||
meta_field_serializer_class = MetaField
|
||||
|
||||
def to_representation(self, value):
|
||||
return OrderedDict([
|
||||
('id', value.pk),
|
||||
('meta', self.meta_field_serializer_class().to_representation(value)),
|
||||
])
|
||||
|
||||
|
||||
class PageParentField(RelatedField):
|
||||
"""
|
||||
Serializes the "parent" field on Page objects.
|
||||
|
||||
Pages don't have a "parent" field so some extra logic is needed to find the
|
||||
parent page. That logic is implemented in this class.
|
||||
|
||||
The representation is the same as the RelatedField class.
|
||||
"""
|
||||
meta_field_serializer_class = PageMetaField
|
||||
|
||||
def get_attribute(self, instance):
|
||||
parent = instance.get_parent()
|
||||
|
||||
site_pages = pages_for_site(self.context['request'].site)
|
||||
if site_pages.filter(id=parent.id).exists():
|
||||
return parent
|
||||
|
||||
|
||||
class ChildRelationField(Field):
|
||||
"""
|
||||
Serializes child relations.
|
||||
|
||||
Child relations are any model that is related to a Page using a ParentalKey.
|
||||
They are used for repeated fields on a page such as carousel items or related
|
||||
links.
|
||||
|
||||
Child objects are part of the pages content so we nest them. The relation is
|
||||
represented as a list of objects.
|
||||
|
||||
Example:
|
||||
|
||||
"carousel_items": [
|
||||
{
|
||||
"title": "First carousel item",
|
||||
"image": {
|
||||
"id": 1,
|
||||
"meta": {
|
||||
"type": "wagtailimages.Image",
|
||||
"detail_url": "http://api.example.com/v1/images/1/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"carousel_items": [
|
||||
{
|
||||
"title": "Second carousel item (no image)",
|
||||
"image": null
|
||||
}
|
||||
]
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.child_fields = kwargs.pop('child_fields')
|
||||
super(ChildRelationField, self).__init__(*args, **kwargs)
|
||||
|
||||
def to_representation(self, value):
|
||||
serializer_class = get_serializer_class(value.model, self.child_fields)
|
||||
serializer = serializer_class()
|
||||
|
||||
return [
|
||||
serializer.to_representation(child_object)
|
||||
for child_object in value.all()
|
||||
]
|
||||
|
||||
|
||||
class StreamField(Field):
|
||||
"""
|
||||
Serializes StreamField values.
|
||||
|
||||
Stream fields are stored in JSON format in the database. We reuse that in
|
||||
the API.
|
||||
|
||||
Example:
|
||||
|
||||
"body": [
|
||||
{
|
||||
"type": "heading",
|
||||
"value": {
|
||||
"text": "Hello world!",
|
||||
"size": "h1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "paragraph",
|
||||
"value": "Some content"
|
||||
}
|
||||
{
|
||||
"type": "image",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
|
||||
Where "heading" is a struct block containing "text" and "size" fields, and
|
||||
"paragraph" is a simple text block.
|
||||
|
||||
Note that foreign keys are represented slightly differently in stream fields
|
||||
to other parts of the API. In stream fields, a foreign key is represented
|
||||
by an integer (the ID of the related object) but elsewhere in the API,
|
||||
foreign objects are nested objects with id and meta as attributes.
|
||||
"""
|
||||
def to_representation(self, value):
|
||||
return value.stream_block.get_prep_value(value)
|
||||
|
||||
|
||||
class TagsField(Field):
|
||||
"""
|
||||
Serializes django-taggit TaggableManager fields.
|
||||
|
||||
These fields are a common way to link tags to objects in Wagtail. The API
|
||||
serializes these as a list of strings taken from the name attribute of each
|
||||
tag.
|
||||
|
||||
Example:
|
||||
|
||||
"tags": ["bird", "wagtail"]
|
||||
"""
|
||||
def to_representation(self, value):
|
||||
return list(value.all().order_by('name').values_list('name', flat=True))
|
||||
|
||||
|
||||
class BaseSerializer(serializers.ModelSerializer):
|
||||
# Add StreamField to serializer_field_mapping
|
||||
serializer_field_mapping = serializers.ModelSerializer.serializer_field_mapping.copy()
|
||||
serializer_field_mapping.update({
|
||||
wagtailcore_fields.StreamField: StreamField,
|
||||
})
|
||||
serializer_related_field = RelatedField
|
||||
|
||||
meta = MetaField()
|
||||
|
||||
def build_property_field(self, field_name, model_class):
|
||||
# TaggableManager is not a Django field so it gets treated as a property
|
||||
field = getattr(model_class, field_name)
|
||||
if isinstance(field, _TaggableManager):
|
||||
return TagsField, {}
|
||||
|
||||
return super(BaseSerializer, self).build_property_field(field_name, model_class)
|
||||
|
||||
|
||||
class PageSerializer(BaseSerializer):
|
||||
meta = PageMetaField()
|
||||
parent = PageParentField(read_only=True)
|
||||
|
||||
def build_relational_field(self, field_name, relation_info):
|
||||
# Find all relation fields that point to child class and make them use
|
||||
# the ChildRelationField class.
|
||||
if relation_info.to_many:
|
||||
model = getattr(self.Meta, 'model')
|
||||
child_relations = {
|
||||
child_relation.field.rel.related_name: get_related_model(child_relation)
|
||||
for child_relation in get_all_child_relations(model)
|
||||
}
|
||||
|
||||
if field_name in child_relations and hasattr(child_relations[field_name], 'api_fields'):
|
||||
return ChildRelationField, {'child_fields': child_relations[field_name].api_fields}
|
||||
|
||||
return super(BaseSerializer, self).build_relational_field(field_name, relation_info)
|
||||
|
||||
|
||||
class ImageSerializer(BaseSerializer):
|
||||
pass
|
||||
|
||||
|
||||
class DocumentSerializer(BaseSerializer):
|
||||
meta = DocumentMetaField()
|
||||
|
||||
|
||||
def get_serializer_class(model_, fields_, base=BaseSerializer):
|
||||
class Meta:
|
||||
model = model_
|
||||
fields = fields_
|
||||
|
||||
return type(model_.__name__ + 'Serializer', (base, ), {
|
||||
'Meta': Meta
|
||||
})
|
||||
|
|
|
|||
|
|
@ -586,7 +586,7 @@ class TestPageDetail(TestCase):
|
|||
self.assertEqual(content['date'], '2013-12-02')
|
||||
|
||||
# Check that the tags were serialised properly
|
||||
self.assertEqual(content['tags'], ['wagtail', 'bird'])
|
||||
self.assertEqual(content['tags'], ['bird', 'wagtail'])
|
||||
|
||||
# Check that the feed image was serialised properly
|
||||
self.assertIsInstance(content['feed_image'], dict)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import logging
|
||||
import requests
|
||||
import json
|
||||
|
||||
from django.utils.six.moves.urllib.parse import urlparse
|
||||
from django.utils.six.moves.urllib.parse import urlparse, urlunparse, urlencode
|
||||
from django.utils.six.moves.urllib.request import Request, urlopen
|
||||
from django.utils.six.moves.urllib.error import URLError, HTTPError
|
||||
|
||||
from requests.adapters import HTTPAdapter
|
||||
from wagtail.wagtailcore import __version__
|
||||
|
||||
|
||||
logger = logging.getLogger('wagtail.frontendcache')
|
||||
|
|
@ -15,44 +17,41 @@ class BaseBackend(object):
|
|||
|
||||
|
||||
class HTTPBackend(BaseBackend):
|
||||
|
||||
class CustomHTTPAdapter(HTTPAdapter):
|
||||
"""
|
||||
Requests will always send requests to whatever server is in the netloc
|
||||
part of the URL. This is a problem with purging the cache as this netloc
|
||||
may point to a different server (such as an nginx instance running in
|
||||
front of the cache).
|
||||
|
||||
This class allows us to send a purge request directly to the cache server
|
||||
with the host header still set correctly. It does this by changing the "url"
|
||||
parameter of get_connection to always point to the cache server. Requests
|
||||
will then use this connection to purge the page.
|
||||
"""
|
||||
def __init__(self, cache_url):
|
||||
self.cache_url = cache_url
|
||||
super(HTTPBackend.CustomHTTPAdapter, self).__init__()
|
||||
|
||||
def get_connection(self, url, proxies=None):
|
||||
return super(HTTPBackend.CustomHTTPAdapter, self).get_connection(self.cache_url, proxies)
|
||||
|
||||
|
||||
def __init__(self, params):
|
||||
self.cache_location = params.pop('LOCATION')
|
||||
|
||||
self.session = requests.Session()
|
||||
self.session.mount('http://', self.CustomHTTPAdapter(self.cache_location))
|
||||
location_url_parsed = urlparse(params.pop('LOCATION'))
|
||||
self.cache_scheme = location_url_parsed.scheme
|
||||
self.cache_netloc = location_url_parsed.netloc
|
||||
|
||||
def purge(self, url):
|
||||
try:
|
||||
response = self.session.request('PURGE', url)
|
||||
except requests.ConnectionError:
|
||||
logger.error("Couldn't purge '%s' from HTTP cache: Connection error", url)
|
||||
return
|
||||
url_parsed = urlparse(url)
|
||||
host = url_parsed.hostname
|
||||
|
||||
# Check for error
|
||||
if response.status_code != 200:
|
||||
logger.error("Couldn't purge '%s' from HTTP cache: Didn't recieve a 200 response (instead, we got '%d %s')", url, response.status_code, response.reason)
|
||||
return
|
||||
# Append port to host if it is set in the original URL
|
||||
if url_parsed.port:
|
||||
host += (':' + str(url_parsed.port))
|
||||
|
||||
request = Request(
|
||||
url=urlunparse([
|
||||
self.cache_scheme,
|
||||
self.cache_netloc,
|
||||
url_parsed.path,
|
||||
url_parsed.params,
|
||||
url_parsed.query,
|
||||
url_parsed.fragment
|
||||
]),
|
||||
headers={
|
||||
'Host': host,
|
||||
'User-Agent': 'Wagtail-frontendcache/' + __version__
|
||||
},
|
||||
method='PURGE'
|
||||
)
|
||||
|
||||
try:
|
||||
urlopen(request)
|
||||
except HTTPError as e:
|
||||
logger.error("Couldn't purge '%s' from HTTP cache. HTTPError: %d %s", url, e.code, e.reason)
|
||||
except URLError as e:
|
||||
logger.error("Couldn't purge '%s' from HTTP cache. URLError: %s", url, e.reason)
|
||||
|
||||
|
||||
class CloudflareBackend(BaseBackend):
|
||||
|
|
@ -62,23 +61,21 @@ class CloudflareBackend(BaseBackend):
|
|||
|
||||
def purge(self, url):
|
||||
try:
|
||||
response = requests.post('https://www.cloudflare.com/api_json.html', {
|
||||
response = urlopen('https://www.cloudflare.com/api_json.html', data=urlencode({
|
||||
'email': self.cloudflare_email,
|
||||
'tkn': self.cloudflare_token,
|
||||
'a': 'zone_file_purge',
|
||||
'z': urlparse(url).netloc,
|
||||
'url': url
|
||||
})
|
||||
except requests.ConnectionError:
|
||||
logger.error("Couldn't purge '%s' from Cloudflare: Connection error", url)
|
||||
}).encode('utf-8'))
|
||||
except HTTPError as e:
|
||||
logger.error("Couldn't purge '%s' from Cloudflare. HTTPError: %d %s", url, e.code, e.reason)
|
||||
return
|
||||
except URLError as e:
|
||||
logger.error("Couldn't purge '%s' from Cloudflare. URLError: %s", url, e.reason)
|
||||
return
|
||||
|
||||
# Check for error
|
||||
if response.status_code != 200:
|
||||
logger.error("Couldn't purge '%s' from Cloudflare: Didn't recieve a 200 response (instead, we got '%d %s')", url, response.status_code, response.reason)
|
||||
return
|
||||
|
||||
response_json = response.json()
|
||||
response_json = json.loads(response.read().decode('utf-8'))
|
||||
if response_json['result'] == 'error':
|
||||
logger.error("Couldn't purge '%s' from Cloudflare: Cloudflare error '%s'", url, response_json['msg'])
|
||||
logger.error("Couldn't purge '%s' from Cloudflare. Cloudflare error '%s'", url, response_json['msg'])
|
||||
return
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ class TestBackendConfiguration(TestCase):
|
|||
self.assertEqual(set(backends.keys()), set(['varnish']))
|
||||
self.assertIsInstance(backends['varnish'], HTTPBackend)
|
||||
|
||||
self.assertEqual(backends['varnish'].cache_location, 'http://localhost:8000')
|
||||
self.assertEqual(backends['varnish'].cache_scheme, 'http')
|
||||
self.assertEqual(backends['varnish'].cache_netloc, 'localhost:8000')
|
||||
|
||||
def test_cloudflare(self):
|
||||
backends = get_backends(backend_settings={
|
||||
|
|
@ -78,7 +79,8 @@ class TestBackendConfiguration(TestCase):
|
|||
|
||||
self.assertEqual(set(backends.keys()), set(['default']))
|
||||
self.assertIsInstance(backends['default'], HTTPBackend)
|
||||
self.assertEqual(backends['default'].cache_location, 'http://localhost:8000')
|
||||
self.assertEqual(backends['default'].cache_scheme, 'http')
|
||||
self.assertEqual(backends['default'].cache_netloc, 'localhost:8000')
|
||||
|
||||
|
||||
PURGED_URLS = []
|
||||
|
|
|
|||
|
|
@ -138,7 +138,5 @@ class RoutablePage(RoutablePageMixin, Page):
|
|||
added to it.
|
||||
"""
|
||||
|
||||
is_abstract = True
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
|
|
|||
|
|
@ -151,8 +151,6 @@ class TestOldStyleRoutablePage(TestNewStyleRoutablePage, WagtailTestUtils):
|
|||
# prevent this class appearing in the global PAGE_MODEL_CLASSES list, as
|
||||
# its non-standard location causes failures when translating from content types
|
||||
# back to models
|
||||
is_abstract = True
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,79 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Lyuboslav Petrov <petrov.lyuboslav@gmail.com>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Bulgarian (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"bg/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: bg\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Запази"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Изтрий %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Изтрий"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Да, изтрий го"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Редакция на %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Редактиране"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Нагоре"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Надолу"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Добави препоръчана страница"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Фрази за търсене"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Дума/Фраза за търсене"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Преглед (последната седмица)"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Нищо"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" Има едно съвпадение\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" Има %(counter)s съвпадения\n"
|
||||
" "
|
||||
Binary file not shown.
|
|
@ -0,0 +1,91 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# David Llop <d.lloople@gmail.com>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Catalan (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"ca/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ca\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Desa"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Esborra %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Esborra"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Si, esborra"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Editant %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Editant"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Puja"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Baixa"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Afegeix una pàgina recomanada"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Termini de cerca"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Cerca paraula(es)"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Vistes(la setmana pasada)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Edita aquesta selecció"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Cap"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
"Hi ha una coincidència"
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
"Hi han %(counter)s coincidències"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Selecció de l'editor per a '{0}' creada."
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Selecció de l'editor per '{0}' actualitzada."
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Selecció de l'editor esborrada."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,169 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# M0rph 3u5 <transifex@m0rph3u5.net>, 2014
|
||||
# pcraston <patrick@craston.com>, 2014
|
||||
# Tammo van Lessen <tvanlessen@gmail.com>, 2015
|
||||
# Wasilis Mandratzis-Walz, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: German (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"de/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: de\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr "Bitte geben Sie mindestens einen Vorschlag für diesen Suchbegriff an."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Seite"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" <p>Hervorgehobene Suchergebnisse sind eine Möglichkeit, bestimmte "
|
||||
"Seiten zu empfehlen die von sich aus nicht sehr weit oben in den "
|
||||
"Suchergebnissen auftauchen würden. So könnte zum Beispiel ihre Spendenseite "
|
||||
"auftauchen wenn nach dem Suchbegriff \"<em>unterstützen</em>\" gesucht wird."
|
||||
"</p>\n"
|
||||
" "
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" <p>Im Eingabefeld \"Suchbegriffe/Phrasen\" müssen sie den "
|
||||
"vollständigen und genauen Suchbegriff, inklusive eventueller "
|
||||
"Rechtschreibfehler, eingeben, für den sie Seiten empfehlen möchten. Zur "
|
||||
"Unterstützung können sie aus häufig verwendeten Suchbegriffen wählen.</p>\n"
|
||||
" "
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "%(query)s löschen"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Sind Sie sicher, dass Sie alle hervorgehobenen Suchergebnisse für diesen "
|
||||
"Suchbegriff löschen wollen?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Ja, löschen"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "%(query)s bearbeiten"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Bearbeiten"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Nach oben"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Nach unten"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Hervorgehobenes Suchergebnis"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Empfohlene Seite hinzufügen"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Suchbegriffe"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Hervorgehobene Suchergebnisse"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Neues hervorgehobenes Suchergebnis hinzufügen"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Suchbegriff/e"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Hervorgehobene Suchergebnisse"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Aufrufe (letze Woche)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Diese Empfehlung bearbeiten"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" Es gibt ein Ergebnis\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" Es gibt %(counter)s Ergebnisse\n"
|
||||
" "
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Leider gibt es keine hervorgehobenen Suchergebnisse, die zu \"<em>"
|
||||
"%(query_string)s</em>\" passen."
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Redaktionsempfehlungen für '{0}' erstellt."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Bearbeiten"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "Empfehlungen konnten wegen eines Fehlers nicht erstellt werden"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Redaktionsempfehlungen für '{0}' geändert."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "Empfehlungen wurden wegen eines Fehlers nicht gespeichert"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Redaktionsempfehlungen gelöscht."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,164 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# dotoree <vdotoree@yahoo.gr>, 2015
|
||||
# serafeim <serafeim@torchbox.com>, 2014
|
||||
# Wasilis Mandratzis-Walz, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Greek (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"el/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: el\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr ""
|
||||
"Παρακαλείστε να διευκρινίσετε τουλάχιστον μία σύσταση για αυτόν τον όρο "
|
||||
"αναζήτησης."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Σελίδα"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Περιγραφή"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Οι επιλογές συντακτών είναι ένας τρόπος πρότασης συγκεκριμένων σελίδων οι "
|
||||
"οποίες κανονικά δε θα βρίσκονται ψηλά στα αποτελέσματα της αναζήτησης. </p>"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"\n"
|
||||
"<p>Το πεδίο \"όρος(οι)/φράσεις\" παρακάτω πρέπει να περιέχει το πλήρες και "
|
||||
"ακριβές κείμενο για το οποίο θέλετε να παρέχετε προτεινόμενα αποτελέσματα, "
|
||||
"<em>συμπεριλαμβανομένων</em> τυχόν ορθογραφικών λαθών. Προς βοήθεια, "
|
||||
"μπορείτε να επιλέξετε όρους αναζήτησης που ήταν δημοφιλείς στους χρήστες.</p>"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Αποθήκευση"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Διαγραφή %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Διαγραφή"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Είστε σίγουρος ότι θέλετε να διαγράψετε όλες τις επιλογές συντακτών για τον "
|
||||
"εν λόγω όρο αναζήτησης;"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Ναι, να διαγραφεί"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Επεξεργασία %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Διόρθωση"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Πάνω"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Κάτω"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Προωθείται το αποτέλεσμα αναζήτησης"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Προσθήκη προτεινόμενης σελίδας"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Όροι αναζήτησης"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Προωθουνται τα αποτέλεσματα αναζήτησης"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Προσθήκη νέου προωθείμενου αποτελέσματος"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Όροι αναζήτησης"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Προωθημενα αποτελέσματα"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Εμφανίσεις (την περασμένη εβδομάδα)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Διόρθωση"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Καμία"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
"Βρέθηκε ένα αποτέλεσμα"
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
"Βρέθηκαν %(counter)s αποτελέσματα"
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Λυπούμαστε, καμία ανακατεύθυνση δε ταιριάζει με το \"<em>%(query_string)s</"
|
||||
"em>\""
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Επιτυχής δημιουργία επιλογή συντακτών για το '{0}'."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Επεξεργασία"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "Οι συστάσεις δεν έχουν δημιουργηθεί λόγω σφαλμάτων"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Επιτυχής διόθρωση επιλογής συντακτών για το '{0}'."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "Οι συστάσεις δεν έχουν αποθηκευτεί λόγω σφαλμάτων"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Επιτυχής διαγραφή επιλογής συντακτών."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,196 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: forms.py:31
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr ""
|
||||
|
||||
#: models.py:9
|
||||
msgid "Page"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:11
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:18
|
||||
msgid "Search promotion"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/add.html:3
|
||||
#: templates/wagtailsearchpromotions/add.html:5
|
||||
msgid "Add search pick"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/add.html:10
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/add.html:14
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/add.html:28
|
||||
#: templates/wagtailsearchpromotions/edit.html:19
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/confirm_delete.html:3
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/confirm_delete.html:5
|
||||
#: templates/wagtailsearchpromotions/edit.html:20
|
||||
#: templates/wagtailsearchpromotions/includes/searchpromotion_form.html:6
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/confirm_delete.html:9
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/confirm_delete.html:12
|
||||
msgid "Yes, delete"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/edit.html:3
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/edit.html:5
|
||||
msgid "Editing"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/includes/searchpromotion_form.html:4
|
||||
msgid "Move up"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/includes/searchpromotion_form.html:5
|
||||
msgid "Move down"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/includes/searchpromotion_form.html:10
|
||||
msgid "Promoted search result"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/includes/searchpromotions_formset.html:16
|
||||
msgid "Add recommended page"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/index.html:3
|
||||
msgid "Search Terms"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/index.html:16 wagtail_hooks.py:30
|
||||
msgid "Promoted search results"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/index.html:17
|
||||
msgid "Add new promoted result"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/list.html:8
|
||||
msgid "Search term(s)"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/list.html:9
|
||||
msgid "Promoted results"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/list.html:10
|
||||
msgid "Views (past week)"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/list.html:17
|
||||
msgid "Edit this pick"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/list.html:23
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/results.html:5
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/results.html:18
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
|
||||
#: templates/wagtailsearchpromotions/results.html:21
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No promoted results have been created. Why not <a href="
|
||||
"\"%(wagtailsearchpromotions_add_url)s\">add one</a>?"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:51
|
||||
msgid "Search promoted results"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:87
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:88 views.py:124
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:95
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:123
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr ""
|
||||
|
||||
#: views.py:131
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:150
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr ""
|
||||
Binary file not shown.
|
|
@ -0,0 +1,186 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# fooflare <amos.oviedo@gmail.com>, 2014
|
||||
# Joaquín Tita <carpincho@gmail.com>, 2014
|
||||
# José Alaguna <alagunajs@gmail.com>, 2015
|
||||
# Mauricio Baeza <web@mauriciobaeza.net>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-27 01:32+0000\n"
|
||||
"Last-Translator: José Alaguna <alagunajs@gmail.com>\n"
|
||||
"Language-Team: Spanish (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"es/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: es\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr ""
|
||||
"Por favor, especifique al menos una recomendación para este término de "
|
||||
"búsqueda."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Página"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
msgid "Search promotion"
|
||||
msgstr "Promover búsqueda"
|
||||
|
||||
msgid "Add search pick"
|
||||
msgstr "Añadir selección de búsqueda"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Resultados promovidos son medios para recomendar páginas específicas que "
|
||||
"pueden no aparecer en los primeros puestos de los resultados de búsqueda. "
|
||||
"Por ejemplo: recomendar un sitio de donaciones utilizando términos menos "
|
||||
"frecuentes como \"<em>donar</em>\".</p>"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>El campo de \"término(s) de búsqueda/frase\", debe contener la búsqueda "
|
||||
"completa y exacta para que se proporcionen los resultados recomendados, "
|
||||
"<em>incluyendo</em> cualquier error de ortografía o error accidental del "
|
||||
"usuario. Para ayudarte, puedes elegir entre los términos de búsqueda que han "
|
||||
"sido más populares entre los usuarios de su sitio.</p>"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Eliminar %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Eliminar"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"¿Esta seguro de querer borrar todos los resultados promocionados para este "
|
||||
"termino de busqueda?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Sí, eliminar"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Editando %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Editando"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Subir"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Bajar"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Resultados de busqueda promocionados"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Añadir página recomendada"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Términos de búsqueda"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Resultados de busqueda promocionados"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Agregar nuevo resultado promocionado"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Término(s) de búsqueda"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Resultados promocionados"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Vistas (semana pasada)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Editar esta selección"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Ninguna"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" Hay una coincidencia\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" Hay %(counter)s coincidencias\n"
|
||||
" "
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Lo sentimos, resultados promovidos no encontrados \"<em>%(query_string)s</em>"
|
||||
"\""
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No promoted results have been created. Why not <a href="
|
||||
"\"%(wagtailsearchpromotions_add_url)s\">add one</a>?"
|
||||
msgstr ""
|
||||
"Resultados promovidos no han sido creados. ¿Por que no <a href="
|
||||
"\"%(wagtailsearchpromotions_add_url)s\">agregar uno</a>?"
|
||||
|
||||
msgid "Search promoted results"
|
||||
msgstr "Buscar resultados promovidos"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Selecciones del editor para '{0}' creadas."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "Las recomendaciones no han sido creadas debido a errores "
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Selecciones del editor para '{0}' actualizadas."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "Las recomendaciones no han sido guardadas debido a errores"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Selecciones del editor para '{0}' eliminadas."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,169 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Adrien <laadrien@gmail.com>, 2014
|
||||
# Bertrand Bordage <bordage.bertrand@gmail.com>, 2015
|
||||
# nahuel, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: French (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"fr/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: fr\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr ""
|
||||
"Veuillez spécifier au moins une recommandation pour ce terme de recherche."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Page"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" <p>Les résultats améliorés sont un moyen de recommander des "
|
||||
"pages spécifiques qui ne seraient pas arrivées naturellement en haut des "
|
||||
"résultats de recherche. Ex: associer votre page de \"soutient\" à une "
|
||||
"recherche utilisateur avec un terme moins explicite comme \"<em>donner</em>"
|
||||
"\".</p>\n"
|
||||
" "
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" <p>Le champ \"Terme(s)/phrase de recherche\" ci-dessous doit "
|
||||
"contenir la recherche complète et exacte pour laquelle vous souhaitez "
|
||||
"fournir des résultats recommandés, <em>ce qui comprend</em> n'importe quelle "
|
||||
"faute de frappe/erreur de l'utilisateur. Pour vous aider, vous pouvez "
|
||||
"choisir parmi les termes de recherche populaires des utilisateurs de votre "
|
||||
"site.</p>\n"
|
||||
" "
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Enregistrer"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Supprimée %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Supprimer"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Êtes-vous sûr de vouloir supprimer tous les résultats améliorés pour ce "
|
||||
"terme de recherche"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Oui, supprimer"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Modification de %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Modification"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Monter"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Descendre"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Résultat de recherche amélioré"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Ajouter une page recommandée"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Termes de recherche"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Résultats de recherche améliorés"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Ajouter un nouveau résultat amélioré"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Terme(s) de recherche"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Résultats améliorés"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Vues (semaine dernière)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Éditer ce choix"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Aucun"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" 1 correspondance "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" %(counter)s correspondances "
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Désolé, aucun résultat amélioré correspondant pour \"<em>%(query_string)s</"
|
||||
"em>\""
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Résultat amélioré pour '{0}' créé."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Modifier"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "Les recommandations n'ont pas été créées en raison d'erreurs"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Résultat amélioré pour '{0}' mis à jour."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "Les recommandations n'ont pas été sauvegardées en raison d'erreurs"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Résultat amélioré supprimé."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,93 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# fooflare <amos.oviedo@gmail.com>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Galician (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"gl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: gl\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Gardar"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Eliminar %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Eliminar"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Sí, eliminar"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Editando %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Editando"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Subir"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Baixar"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Engadir páxina recomendada"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Termos de busca"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Termos(s) de busca"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Vistas (semana pasada)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Editar esta selección"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Ningunha"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" Hai unha coincidencia\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" Hai %(counter)s coincidencias\n"
|
||||
" "
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Seleccións do editor para '{0}' creadas."
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Seleccións do editor para '{0}' actualizadas."
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Seleccións do editor para '{0}' eliminadas."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,101 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# bjesus <bjesus@gmail.com>, 2015
|
||||
# lior abazon <abazon@v15.org.il>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Hebrew (Israel) (http://www.transifex.com/torchbox/wagtail/"
|
||||
"language/he_IL/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: he_IL\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr "אנא ציין לפחות המלצה אחת למונח חיפוש זה"
|
||||
|
||||
msgid "Page"
|
||||
msgstr "עמוד"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "תיאור"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "שמור"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "מחיקה"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"האם אתם בטוחים כי ברצונכם למחוק את כל התוצאות המקודמות עבור מונח חיפוש זה?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "כן, מחק"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "עריכת %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "עריכה"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "העבר מעלה"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "העבר מטה"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "קדם תוצאת חיפוש"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "הוסף עמוד מומלץ"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "מושגי חיפוש"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "תוצאות חיפוש מקודמות "
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "הוסף תוצאה מקודמת חדשה"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "תוצאות מקודמות "
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "ערוך בחירה זו"
|
||||
|
||||
msgid "None"
|
||||
msgstr "אף אחת"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "בחירת העורך עבור '{0}' נוצרה"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "ערוך"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "המלצות לא נשמרו בעקבות שגיאה"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "בחירת העורך עבור '{0}' עודכנה"
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "ההמלצות לא נשמרו עקב שגיאות"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "בחירת העורך נמחקה"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,170 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Claudio Bantaloukas <rockdreamer@gmail.com>, 2015
|
||||
# Giacomo Ghizzani <giacomo.ghz@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Italian (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"it/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: it\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr ""
|
||||
"Si prega di specificare almeno una raccomandazione per questo termine di "
|
||||
"ricerca."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Pagina"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descrizione"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" <p>I risultati di ricerca sponsorizzati sono un mezzo di "
|
||||
"raccomandare pagine specifiche che potrebbero non salire organicamente in "
|
||||
"alto nei risultati dei motori di ricerca. Ad esempio, raccomanda la tua "
|
||||
"pagina primaria donazione a un utente che fa una ricerca con il termine "
|
||||
"comune \"<em>dare</em>\".</p>\n"
|
||||
" "
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" <p>Il campo \"Termine(i)/frase\" qui sotto deve contenere la "
|
||||
"ricerca intera e esatta per cui vuoi sponsorizzare un risultato, "
|
||||
"<em>incluso</em> anche ogni errore di battitura dell'utente. Puoi aiutarti "
|
||||
"scegliendo fra i termini di ricerca più popolari degli utenti del tuo sito.</"
|
||||
"p>\n"
|
||||
" "
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Salva"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Elimina %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Elimina"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Sei sicuro di voler eliminare tutti i risultati di ricerca sponsorizzati per "
|
||||
"questo termine di ricerca?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Si, elimina"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Modifica %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Modifica"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Vai su"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Vai giù"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Risultati di ricerca sponsorizzati"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Aggiungi pagina raccomandata"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Termini di ricerca"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Risultati di ricerca promozionati"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Aggiungi nuovo risultato sponsorizzato"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Termine(i) di ricerca"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Risultati promozionati"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Viste (scorsa settimana)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Modifica questa scelta"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Nessuno"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" C'è una corrispondenza\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" Ci sono %(counter)s corrispondenze\n"
|
||||
" "
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Spiacente, nessun risultato promozionato corrispondente a \"<em>"
|
||||
"%(query_string)s</em>\""
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Scelta dalla redazione per '{0}' creata."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Modifica"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "Raccomandazione non creata a causa di errori"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Scelta dalla redazione per '{0}' aggiornata."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "Raccomandazione non salvata a causa di errori"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Scelta dalla redazione eliminata."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,153 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Ji Han Chung <jihanchung20@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Korean (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"ko/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ko\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr "이 검색어를 위해 최소 한개의 추천을 지정하여 주시기 바랍니다."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "페이지"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "설명"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>프로모션 검색 결과는 일반적인 검색 결과에서 먼저 나오지 않는 추천을 위한 "
|
||||
"특정 페이지들입니다. 예를 들어, 일반적이지 않은 \"<em>기부</em>\"같은 단어"
|
||||
"를 검색한 사용자에게, 후원 페이지를 추천하는 형태입니다.</p>"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>아래의 \"검색어/문장\" 필드는 틀린 철자/사용자 에러를 <em>포함한</em> 내용"
|
||||
"에 대한 추천 결과를 제공하기 위해 정확한 검색어를 넣어야 합니다. 지원을 위"
|
||||
"해 당신은 사이트의 유명한 검색어 중 선택할 수 있습니다. </p>"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "저장"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "%(query)s 삭제"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "삭제"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr "이 검색어와 관련된 모든 프로모션 결과들을 정말 삭제할까요?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "네, 지우겠습니다."
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "%(query)s 수정"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "수정중"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "위로 이동"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "아래로 이동"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "프로모션 검색 결과"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "추천 페이지 추가"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "검색어"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "프로모션 검색 결과"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "새로운 프로모션 결과 추가"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "검색어"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "프로모션 결과"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "본 횟수(지난 주)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "선택 수정"
|
||||
|
||||
msgid "None"
|
||||
msgstr "없음"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
"%(counter)s 개의 연관된 결과가 있습니다"
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"죄송합니다, \"<em>%(query_string)s</em>\" 와 연관된 프로모션 결과가 없습니다."
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "'{0}' 를 위한 에디터의 선택이 추가 되었습니다."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "수정"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "에러로 인해 추천결과를 생성할 수 없습니다"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "'{0}' 를 위한 에디터의 선택이 업데이트 되었습니다."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "에러로 인해 추천결과를 저장할 수 없습니다"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "에디터의 선택이 삭제 되었습니다."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,182 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Eirik Krogstad <eirikkr@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-09-02 14:43+0000\n"
|
||||
"Last-Translator: Eirik Krogstad <eirikkr@gmail.com>\n"
|
||||
"Language-Team: Norwegian Bokmål (http://www.transifex.com/torchbox/wagtail/"
|
||||
"language/nb/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: nb\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr "Vennligst spesifiser minst en anbefaling for dette søkeordet."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Side"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Beskrivelse"
|
||||
|
||||
msgid "Search promotion"
|
||||
msgstr "Søkepromotering"
|
||||
|
||||
msgid "Add search pick"
|
||||
msgstr "Legg til søkevalg"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Forfremmede søkeresultater er en måte å anbefale spesifikke sider som "
|
||||
"ikke nødvendigvis kommer høyt opp i søkeresultater. Feks. kan man anbefale "
|
||||
"kontaktsiden for en bruker som søker etter ordet <em>\"tilbakemelding\"</em>."
|
||||
"</p>\n"
|
||||
" "
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Feltet \"Søkeord/-frase\" under må inneholde den fullstendige og eksakte "
|
||||
"søkestrengen som du ønsker å gi anbefalinger for, <em>inkludert</em> vanlige "
|
||||
"feilstavinger eller andre brukerfeil. Det kan være nyttig å se på hvilke "
|
||||
"søkeord som har vært mye brukt på nettstedet.</p>\n"
|
||||
" "
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Lagre"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Slett %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Slett"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Er du sikker på at du vil slette alle forfremmede resultater for dette "
|
||||
"søkeordet?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Ja, slett"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Endrer %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Endrer"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Flytt opp"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Flytt ned"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Forfremmet søkeresultat"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Legg til anbefalt side"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Søkeord"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Forfremmede søkeresultater"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Legg til nytt forfremmet resultat"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Søkeord"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Forfremmede resultater"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Visninger (siste uke)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Endre dette resultatet"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Ingen"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
"Det er ett treff\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
"Det er %(counter)s treff\n"
|
||||
" "
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Beklager, ingen forfremmede resultater samsvarer med \"<em>%(query_string)s</"
|
||||
"em>\""
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"No promoted results have been created. Why not <a href="
|
||||
"\"%(wagtailsearchpromotions_add_url)s\">add one</a>?"
|
||||
msgstr ""
|
||||
"Ingen forfremmede resultater har blitt opprettet. Hvorfor ikke <a href="
|
||||
"\"%(wagtailsearchpromotions_add_url)s\">legge til et</a>?"
|
||||
|
||||
msgid "Search promoted results"
|
||||
msgstr "Søk i forfremmede resultater"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Redaktørvalg for \"{0}\" er opprettet."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Endre"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "Anbefalinger kunne ikke opprettes grunnet feil"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Redaktørvalg for \"{0}\" oppdatert."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "Anbefalinger kunne ikke lagres grunnet feil"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Redaktørvalg slettet."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,98 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# utek <mail@utek.pl>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Polish (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"pl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pl\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Zapisz"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Usuń %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Usuń"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Tak, usuń"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Edycja %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Edytujesz"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Przesuń w górę"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Przesuń w dół"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Dodaj polecaną stronę"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Frazy wyszukiwania"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Frazy wyszukiwania"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Odsłony (poprzedni tydzień)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Edytuj ten wybór"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Brak"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" Jedno dopasowanie\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" Są %(counter)s dopasowania\n"
|
||||
" "
|
||||
msgstr[2] ""
|
||||
"\n"
|
||||
" Jest %(counter)s dopasowań\n"
|
||||
" "
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Stworzono wybór redakcji dla '{0}'"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Zaktualizowano wybór redakcji dla '{0}'."
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Usunięto wybór redakcji."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,163 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Claudemiro Alves Feitosa Neto <dimiro1@gmail.com>, 2015
|
||||
# Gladson <gladsonbrito@gmail.com>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/torchbox/"
|
||||
"wagtail/language/pt_BR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_BR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr "Especifique pelo menos uma recomendação para este termo de busca."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Página"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descrição"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Resultados de busca promovidos são meios de recomendar páginas "
|
||||
"específicas que pode não aparecer organicamente nos resultados. Ex. "
|
||||
"recomendar sua página de doação principal para um usuário pesquisando com um "
|
||||
"termo menos comum \"<em>doando</em>\".</p>"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>O \"Termo(s)/frase da busca\" abaixo devem conter a busca exata e "
|
||||
"completa para a qual você deseja provê resultados recomendados, "
|
||||
"<em>incluíndo</em> qualquer erro de digitação ou do usuário. Para ajudar, "
|
||||
"você pode escolher a partir de termos que são populares entre os usuários de "
|
||||
"seu site</p>"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Salvar"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Excluir %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Excluir"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Você tem certeza que você quer excluir todos os resultados promovidos para "
|
||||
"este termo?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Sim, apague"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Editando %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Editando"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Mover para cima"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Mover para baixo"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Resultado promovido"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Adicionar recomendação para página"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Procurar Termos"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Resultados promovidos"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Adicionar um novo resultado promovido"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Procurar termo(s)"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Resultados promovidos"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Visualizações (última semana)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Editar sugestão do editor"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Nenhum"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
" Há um resultado\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
" Há %(counter)s resultados\n"
|
||||
" "
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr "Desculpe, nenhum resultado promovido com \"<em>%(query_string)s</em>\""
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Sugestões dos editores para '{0}' criados."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "As recomendações não poderiam ser criadas devido a erros"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Sugestões do editor para '{0}' atualizado."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "As recomendações não puderam ser salvas devido a erros"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Sugestões do editor deletado."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,168 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Gladson <gladsonbrito@gmail.com>, 2014
|
||||
# Tiago Henriques <trinosauro@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/torchbox/"
|
||||
"wagtail/language/pt_PT/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_PT\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr ""
|
||||
"Por favor especifique pelo menos uma recomendação para este termo de "
|
||||
"pesquisa."
|
||||
|
||||
msgid "Page"
|
||||
msgstr "Página"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descrição"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Os resultados de pesquisa promovidos servem para recomendar páginas "
|
||||
"específicas que podem não aparecer bem posicionadas nos resultados de "
|
||||
"pesquisa. Por exemplo, recomendar a sua página principal de donativos a um "
|
||||
"utilizador que pesquisa um termo menos comum como \"<em>dar</em>\".</p>\n"
|
||||
" "
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>O campo \"Pesquisar termo(s)/frase\" abaixo tem de conter a pesquisa "
|
||||
"completa e exata para a qual pretende obter resultados recomendados, "
|
||||
"<em>incluindo</em> quaisquer erros de ortografia/utilizador. Para facilitar, "
|
||||
"pode escolher de entre os termos de pesquisa que são frequentemente usados "
|
||||
"pelos utilizadores do seu site.</p>\n"
|
||||
" "
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Apagar %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Apagar"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Tem a certeza que quer apagar todos os resultados promovidos para este termo "
|
||||
"de pesquisa?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Sim, apagar"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "A editar %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "A editar"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Mover para cima"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Mover para baixo"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Resultado de pesquisa promovido"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Adicionar uma página recomendada"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Pesquisar Termos"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Resultados de pesquisa promovidos"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Adicionar novo resultado promovido"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Pesquisar termo(s)"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Resultados promovidos"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Visualizações (última semana)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Editar esta escolha"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Nenhuma"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
"Encontrado um resultado\n"
|
||||
" "
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
"Encontrados %(counter)s resultados\n"
|
||||
" "
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Desculpe, nenhuma resultado promovido contém \"<em>%(query_string)s</em>\""
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Escolhas do editor para '{0}' criadas."
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "As recomendações não foram criadas devido a erros."
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Escolhas do editor para '{0}' atualizadas."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "As recomendações não foram guardadas devido a erros."
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Escolhas do editor apagadas."
|
||||
Binary file not shown.
|
|
@ -0,0 +1,157 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Dan Braghis, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Romanian (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"ro/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ro\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?"
|
||||
"2:1));\n"
|
||||
|
||||
msgid "Please specify at least one recommendation for this search term."
|
||||
msgstr "Introduceți cel puțin o recomandare pentru acest termen de căutare."
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>Promoted search results are a means of recommending "
|
||||
"specific pages that might not organically come high up in search results. E."
|
||||
"g recommending your primary donation page to a user searching with the less "
|
||||
"common term \"<em>giving</em>\".</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Rezultatele de căutare promovate reprezintă o modalitate de recomandare a "
|
||||
"paginilor care pot să nu apară în topul rezultatelor de căutare în mod "
|
||||
"organic. De exemplu, recomandărea paginii principale de donații unui "
|
||||
"utilizator care caută termenul mai puțin frecvent \"<em>dare</em>\".</p>\n"
|
||||
" "
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
" <p>The \"Search term(s)/phrase\" field below must contain "
|
||||
"the full and exact search for which you wish to provide recommended results, "
|
||||
"<em>including</em> any misspellings/user error. To help, you can choose from "
|
||||
"search terms that have been popular with users of your site.</p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p>Câmpul \"Termeni/frază de căutare\" de mai jos trebuie să conțină șirul "
|
||||
"exact pentru care doriți să furnizați rezultate recomandate. <em>Includeți</"
|
||||
"em> greșeli ortografice și alte greșeli. Puteți să alegeți din termenii de "
|
||||
"căutare populari printre utilizatorii sitului dvs.</p>"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Salvează"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "Șterge %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Șterge"
|
||||
|
||||
msgid ""
|
||||
"Are you sure you want to delete all promoted results for this search term?"
|
||||
msgstr ""
|
||||
"Sigur doriți să ștergeți toate rezultatele promovate pentru acest termen de "
|
||||
"căutare?"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "Da, șterge"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "Editare %(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "Editare"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "Deplasează în sus"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "Deplasează în jos"
|
||||
|
||||
msgid "Promoted search result"
|
||||
msgstr "Rezultat de căutare promovat"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "Adaugă pagină recomandată"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "Termeni de căutare"
|
||||
|
||||
msgid "Promoted search results"
|
||||
msgstr "Rezultate de căutare promovate"
|
||||
|
||||
msgid "Add new promoted result"
|
||||
msgstr "Adaugă rezultat promovat"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "Termen de căutare"
|
||||
|
||||
msgid "Promoted results"
|
||||
msgstr "Rezultate promovate"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "Vizualizări (ultima săptămână)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "Editează selecția"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Nici una"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" There is one match\n"
|
||||
" "
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
" There are %(counter)s matches\n"
|
||||
" "
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
"Există o potrivire"
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
"Sunt %(counter)s potriviri"
|
||||
msgstr[2] ""
|
||||
"\n"
|
||||
"Sunt %(counter)s potriviri"
|
||||
|
||||
#, python-format
|
||||
msgid "Sorry, no promoted results match \"<em>%(query_string)s</em>\""
|
||||
msgstr ""
|
||||
"Ne pare rău, \"<em>%(query_string)s</em>\" nu se potrivește cu nici un "
|
||||
"rezultat promovat"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "Selecțiile editoriale pentru '{0}' au fost create."
|
||||
|
||||
msgid "Recommendations have not been created due to errors"
|
||||
msgstr "Recomandările nu au fost create din cauza erorilor."
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "Selecțiile editoriale pentru '{0}' au fost actualizate."
|
||||
|
||||
msgid "Recommendations have not been saved due to errors"
|
||||
msgstr "Recomandările nu au fost salvate din cauza erorilor."
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "Selecțiile editoriale au fost șterse"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,74 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Chinese (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"zh/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: zh\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "删除Delete %(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "删除"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "是的,删除"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "编辑%(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "编辑"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "向上移动"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "向下移动"
|
||||
|
||||
msgid "Add recommended page"
|
||||
msgstr "添加推荐页"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "搜索关键词"
|
||||
|
||||
msgid "Search term(s)"
|
||||
msgstr "搜索关键词"
|
||||
|
||||
msgid "Views (past week)"
|
||||
msgstr "查看 (上周)"
|
||||
|
||||
msgid "Edit this pick"
|
||||
msgstr "编辑这个精选"
|
||||
|
||||
msgid "None"
|
||||
msgstr "没有"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' created."
|
||||
msgstr "编辑精选'{0}'已创建。"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Editor's picks for '{0}' updated."
|
||||
msgstr "编辑精选'{0}'已更新。"
|
||||
|
||||
msgid "Editor's picks deleted."
|
||||
msgstr "编辑精选已删除"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,58 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# hanfeng <appweb.cn@gmail.com>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:46+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 14:14+0000\n"
|
||||
"Last-Translator: Karl Hobley <karl@torchbox.com>\n"
|
||||
"Language-Team: Chinese (China) (http://www.transifex.com/torchbox/wagtail/"
|
||||
"language/zh_CN/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: zh_CN\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
msgid "Page"
|
||||
msgstr "页面"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "描述"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
#, python-format
|
||||
msgid "Delete %(query)s"
|
||||
msgstr "删除%(query)s"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "删除"
|
||||
|
||||
msgid "Yes, delete"
|
||||
msgstr "是,删除"
|
||||
|
||||
#, python-format
|
||||
msgid "Editing %(query)s"
|
||||
msgstr "编辑%(query)s"
|
||||
|
||||
msgid "Editing"
|
||||
msgstr "编辑"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr "上移"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr "下移"
|
||||
|
||||
msgid "Search Terms"
|
||||
msgstr "检索词"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "编辑"
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
from django import template
|
||||
|
||||
from wagtail.wagtailsearch.models import Query
|
||||
from wagtail.contrib.wagtailsearchpromotions.models import SearchPromotion
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
|
@ -8,4 +9,7 @@ register = template.Library()
|
|||
|
||||
@register.assignment_tag()
|
||||
def get_search_promotions(search_query):
|
||||
return Query.get(search_query).editors_picks.all()
|
||||
if search_query:
|
||||
return Query.get(search_query).editors_picks.all()
|
||||
else:
|
||||
return SearchPromotion.objects.none()
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ class TestGetSearchPromotionsTemplateTag(TestCase):
|
|||
search_picks = list(get_search_promotions("root page"))
|
||||
self.assertEqual(search_picks, [pick])
|
||||
|
||||
def test_get_search_promotions_with_none_query_string(self):
|
||||
search_picks = list(get_search_promotions(None))
|
||||
self.assertEqual(search_picks, [])
|
||||
|
||||
|
||||
class TestSearchPromotionsIndexView(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@ from wagtail.wagtailsearch import forms as search_forms
|
|||
from wagtail.wagtailsearch.models import Query
|
||||
from wagtail.wagtailadmin.forms import SearchForm
|
||||
from wagtail.wagtailadmin import messages
|
||||
from wagtail.wagtailadmin.utils import permission_required, any_permission_required
|
||||
|
||||
from wagtail.contrib.wagtailsearchpromotions import forms
|
||||
|
||||
|
||||
@any_permission_required('wagtailsearchpromotions.add_searchpromotion', 'wagtailsearchpromotions.change_searchpromotion', 'wagtailsearchpromotions.delete_searchpromotion')
|
||||
@vary_on_headers('X-Requested-With')
|
||||
def index(request):
|
||||
is_searching = False
|
||||
|
|
@ -71,6 +73,7 @@ def save_searchpicks(query, new_query, searchpicks_formset):
|
|||
return False
|
||||
|
||||
|
||||
@permission_required('wagtailsearchpromotions.add_searchpromotion')
|
||||
def add(request):
|
||||
if request.POST:
|
||||
# Get query
|
||||
|
|
@ -102,6 +105,7 @@ def add(request):
|
|||
})
|
||||
|
||||
|
||||
@permission_required('wagtailsearchpromotions.change_searchpromotion')
|
||||
def edit(request, query_id):
|
||||
query = get_object_or_404(Query, id=query_id)
|
||||
|
||||
|
|
@ -137,6 +141,7 @@ def edit(request, query_id):
|
|||
})
|
||||
|
||||
|
||||
@permission_required('wagtailsearchpromotions.delete_searchpromotion')
|
||||
def delete(request, query_id):
|
||||
query = get_object_or_404(Query, id=query_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from django.core import urlresolvers
|
||||
from django.conf.urls import include, url
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
from wagtail.wagtailcore import hooks
|
||||
from wagtail.contrib.wagtailsearchpromotions import admin_urls
|
||||
|
|
@ -17,10 +18,19 @@ def register_admin_urls():
|
|||
|
||||
class SearchPicksMenuItem(MenuItem):
|
||||
def is_shown(self, request):
|
||||
# TEMPORARY: Only show if the user is a superuser
|
||||
return request.user.is_superuser
|
||||
return (
|
||||
request.user.has_perm('wagtailsearchpromotions.add_searchpromotion')
|
||||
or request.user.has_perm('wagtailsearchpromotions.change_searchpromotion')
|
||||
or request.user.has_perm('wagtailsearchpromotions.delete_searchpromotion')
|
||||
)
|
||||
|
||||
|
||||
@hooks.register('register_settings_menu_item')
|
||||
def register_search_picks_menu_item():
|
||||
return SearchPicksMenuItem(_('Promoted search results'), urlresolvers.reverse('wagtailsearchpromotions:index'), classnames='icon icon-pick', order=900)
|
||||
|
||||
|
||||
@hooks.register('register_permissions')
|
||||
def register_permissions():
|
||||
return Permission.objects.filter(content_type__app_label='wagtailsearchpromotions',
|
||||
codename__in=['add_searchpromotion', 'change_searchpromotion', 'delete_searchpromotion'])
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-03-06 12:05+0000\n"
|
||||
"POT-Creation-Date: 2015-08-26 14:28+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
@ -30,26 +30,26 @@ msgstr ""
|
|||
msgid "Delete image"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:45
|
||||
#: views.py:42
|
||||
msgid "Search something"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:49
|
||||
#: views.py:46
|
||||
msgid "Success message"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:50 views.py:54 views.py:58
|
||||
#: views.py:47 views.py:51 views.py:55
|
||||
msgid "View live"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:51 views.py:55 views.py:59
|
||||
#: views.py:48 views.py:52 views.py:56
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:53
|
||||
#: views.py:50
|
||||
msgid "Warning message"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:57
|
||||
#: views.py:54
|
||||
msgid "Error message"
|
||||
msgstr ""
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,47 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# José Alaguna <alagunajs@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:28+0100\n"
|
||||
"PO-Revision-Date: 2015-08-27 01:40+0000\n"
|
||||
"Last-Translator: José Alaguna <alagunajs@gmail.com>\n"
|
||||
"Language-Team: Spanish (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"es/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: es\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Styleguide"
|
||||
msgstr "Guía de estilo"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
msgid "Delete image"
|
||||
msgstr "Eliminar imagen"
|
||||
|
||||
msgid "Search something"
|
||||
msgstr "Buscar algo"
|
||||
|
||||
msgid "Success message"
|
||||
msgstr "Mensaje de éxito"
|
||||
|
||||
msgid "View live"
|
||||
msgstr "Ver en vivo"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
msgid "Warning message"
|
||||
msgstr "Mensaje de advertencia"
|
||||
|
||||
msgid "Error message"
|
||||
msgstr "Mensaje de error"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,47 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Arnar Tumi Þorsteinsson <arnartumi@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:28+0100\n"
|
||||
"PO-Revision-Date: 2015-08-31 20:31+0000\n"
|
||||
"Last-Translator: Arnar Tumi Þorsteinsson <arnartumi@gmail.com>\n"
|
||||
"Language-Team: Icelandic (Iceland) (http://www.transifex.com/torchbox/"
|
||||
"wagtail/language/is_IS/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: is_IS\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
|
||||
|
||||
msgid "Styleguide"
|
||||
msgstr "Stílblað"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Vista"
|
||||
|
||||
msgid "Delete image"
|
||||
msgstr "Eyða mynd"
|
||||
|
||||
msgid "Search something"
|
||||
msgstr "Leita"
|
||||
|
||||
msgid "Success message"
|
||||
msgstr "Jákvæð skilaboð"
|
||||
|
||||
msgid "View live"
|
||||
msgstr "Skoða lifandi"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Breyta"
|
||||
|
||||
msgid "Warning message"
|
||||
msgstr "Viðvörunar skilaboð"
|
||||
|
||||
msgid "Error message"
|
||||
msgstr "Villu skilaboð"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,47 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Eirik Krogstad <eirikkr@gmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:28+0100\n"
|
||||
"PO-Revision-Date: 2015-09-01 22:14+0000\n"
|
||||
"Last-Translator: Eirik Krogstad <eirikkr@gmail.com>\n"
|
||||
"Language-Team: Norwegian Bokmål (http://www.transifex.com/torchbox/wagtail/"
|
||||
"language/nb/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: nb\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Styleguide"
|
||||
msgstr "Stilguide"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Lagre"
|
||||
|
||||
msgid "Delete image"
|
||||
msgstr "Slett bilde"
|
||||
|
||||
msgid "Search something"
|
||||
msgstr "Søk etter noe"
|
||||
|
||||
msgid "Success message"
|
||||
msgstr "Positiv tilbakemeldning"
|
||||
|
||||
msgid "View live"
|
||||
msgstr "Se publisert"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Rediger"
|
||||
|
||||
msgid "Warning message"
|
||||
msgstr "Advarsel"
|
||||
|
||||
msgid "Error message"
|
||||
msgstr "Feilmelding"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,48 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Dan Braghis, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:28+0100\n"
|
||||
"PO-Revision-Date: 2015-09-02 21:38+0000\n"
|
||||
"Last-Translator: Dan Braghis\n"
|
||||
"Language-Team: Romanian (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"ro/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ro\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?"
|
||||
"2:1));\n"
|
||||
|
||||
msgid "Styleguide"
|
||||
msgstr "Ghid de stil"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Salveză"
|
||||
|
||||
msgid "Delete image"
|
||||
msgstr "Șterge imagine"
|
||||
|
||||
msgid "Search something"
|
||||
msgstr "Caută ceva"
|
||||
|
||||
msgid "Success message"
|
||||
msgstr "Mesaj de success"
|
||||
|
||||
msgid "View live"
|
||||
msgstr "Vezi în direct"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Editează"
|
||||
|
||||
msgid "Warning message"
|
||||
msgstr "Mesaj de avertizare"
|
||||
|
||||
msgid "Error message"
|
||||
msgstr "Mesaj de eroare"
|
||||
Binary file not shown.
|
|
@ -0,0 +1,49 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Eugene MechanisM <contact@mechanism.name>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Wagtail\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-08-26 14:28+0100\n"
|
||||
"PO-Revision-Date: 2015-08-26 21:47+0000\n"
|
||||
"Last-Translator: Eugene MechanisM <contact@mechanism.name>\n"
|
||||
"Language-Team: Russian (http://www.transifex.com/torchbox/wagtail/language/"
|
||||
"ru/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ru\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
|
||||
"%100>=11 && n%100<=14)? 2 : 3);\n"
|
||||
|
||||
msgid "Styleguide"
|
||||
msgstr "Гид по стилям"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Сохранить"
|
||||
|
||||
msgid "Delete image"
|
||||
msgstr "Удалить изображение"
|
||||
|
||||
msgid "Search something"
|
||||
msgstr "Искать что-нибудь"
|
||||
|
||||
msgid "Success message"
|
||||
msgstr "Сообщение об успехе"
|
||||
|
||||
msgid "View live"
|
||||
msgstr "Смотреть на сайте"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Правка"
|
||||
|
||||
msgid "Warning message"
|
||||
msgstr "Сообщение с предупреждением"
|
||||
|
||||
msgid "Error message"
|
||||
msgstr "Сообщение с ошибкой"
|
||||
|
|
@ -301,6 +301,22 @@
|
|||
|
||||
</section>
|
||||
|
||||
<section id="button-groups">
|
||||
<h2>Button groups</h2>
|
||||
<p>Adds rounding to first and last items only</p>
|
||||
<div class="button-group">
|
||||
<button>button element</button>
|
||||
<button>button element</button>
|
||||
<button>button element</button>
|
||||
</div>
|
||||
<br />
|
||||
<div class="button-group">
|
||||
<button class="icon text-replace yes icon-tick">A proper button</button>
|
||||
<a href="#" class="button icon text-replace white icon-cog">A link button</a>
|
||||
<span class="button icon text-replace no icon-bin">A non-link button</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="dropdowns">
|
||||
<h2>Dropdown buttons</h2>
|
||||
|
||||
|
|
@ -374,7 +390,7 @@
|
|||
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans %}
|
||||
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans add_link="wagtailimages_add_image" icon="image" add_text="button" search_url="wagtailimages:index" %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=title_trans add_link="wagtailimages:add" icon="image" add_text="button" search_url="wagtailimages:index" %}
|
||||
</section>
|
||||
|
||||
<section id="forms">
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ from django import forms
|
|||
from django.shortcuts import render
|
||||
from django.utils.translation import ugettext as _
|
||||
from wagtail.wagtailadmin import messages
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
|
||||
from wagtail.wagtailadmin.forms import SearchForm
|
||||
from wagtail.wagtailadmin.widgets import AdminPageChooser, AdminDateInput, AdminTimeInput, AdminDateTimeInput
|
||||
from wagtail.wagtailimages.widgets import AdminImageChooser
|
||||
from wagtail.wagtaildocs.widgets import AdminDocumentChooser
|
||||
|
||||
|
||||
class ExampleForm(forms.Form):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ExampleForm, self).__init__(*args, **kwargs)
|
||||
|
|
@ -37,8 +37,6 @@ class ExampleForm(forms.Form):
|
|||
document_chooser = forms.BooleanField(required=True)
|
||||
|
||||
|
||||
|
||||
@permission_required('wagtailadmin.access_admin')
|
||||
def index(request):
|
||||
|
||||
form = SearchForm(placeholder=_("Search something"))
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
Django>=1.8,<1.9
|
||||
wagtail==1.0
|
||||
wagtail==1.1rc1
|
||||
|
|
|
|||
72
wagtail/tests/dummy_external_storage.py
Normal file
72
wagtail/tests/dummy_external_storage.py
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# This file contains a file storage backend that imitates behaviours of
|
||||
# common external storage backends (S3 boto, libcloud, etc).
|
||||
|
||||
# The following behaviours have been added to this backend:
|
||||
# - Calling .path on the storage or image file raises NotImplementedError
|
||||
# - File.open() after the file has been closed raises an error
|
||||
|
||||
from django.core.files.storage import Storage, FileSystemStorage
|
||||
from django.core.files.base import File
|
||||
from django.utils.deconstruct import deconstructible
|
||||
|
||||
|
||||
@deconstructible
|
||||
class DummyExternalStorage(Storage):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.wrapped = FileSystemStorage(*args, **kwargs)
|
||||
|
||||
def path(self, name):
|
||||
# Overridden to give it the behaviour of the base Storage class
|
||||
# This is what an external storage backend would have
|
||||
raise NotImplementedError("This backend doesn't support absolute paths.")
|
||||
|
||||
def _open(self, name, mode='rb'):
|
||||
# Overridden to return a DummyExternalStorageFile instead of a normal
|
||||
# File object
|
||||
return DummyExternalStorageFile(open(self.wrapped.path(name), mode))
|
||||
|
||||
|
||||
# Wrap all other functions
|
||||
|
||||
def _save(self, name, content):
|
||||
return self.wrapped._save(name, content)
|
||||
|
||||
def delete(self, name):
|
||||
self.wrapped.delete(name)
|
||||
|
||||
def exists(self, name):
|
||||
return self.wrapped.exists(name)
|
||||
|
||||
def listdir(self, path):
|
||||
return self.wrapped.listdir(path)
|
||||
|
||||
def size(self, name):
|
||||
return self.wrapped.size(name)
|
||||
|
||||
def url(self, name):
|
||||
return self.wrapped.url(name)
|
||||
|
||||
def accessed_time(self, name):
|
||||
return self.wrapped.accessed_time(name)
|
||||
|
||||
def created_time(self, name):
|
||||
return self.wrapped.created_time(name)
|
||||
|
||||
def modified_time(self, name):
|
||||
return self.wrapped.modified_time(name)
|
||||
|
||||
|
||||
class DummyExternalStorageFile(File):
|
||||
def open(self, mode=None):
|
||||
# Based on: https://github.com/django/django/blob/2c39f282b8389f47fee4b24e785a58567c6c3629/django/core/files/base.py#L135-L141
|
||||
|
||||
# I've commented out two lines of this function which stops it checking
|
||||
# the filesystem for the file. Making it behave as if it is using an
|
||||
# external file storage.
|
||||
|
||||
if not self.closed:
|
||||
self.seek(0)
|
||||
# elif self.name and os.path.exists(self.name):
|
||||
# self.file = open(self.name, mode or self.mode)
|
||||
else:
|
||||
raise ValueError("The file cannot be reopened.")
|
||||
23
wagtail/tests/snippets/migrations/0002_searchablesnippet.py
Normal file
23
wagtail/tests/snippets/migrations/0002_searchablesnippet.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import wagtail.wagtailsearch.index
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('snippetstests', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SearchableSnippet',
|
||||
fields=[
|
||||
('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')),
|
||||
('text', models.CharField(max_length=255)),
|
||||
],
|
||||
bases=(models.Model, wagtail.wagtailsearch.index.Indexed),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
|
||||
from wagtail.wagtailsearch import index
|
||||
|
||||
from wagtail.wagtailsnippets.models import register_snippet
|
||||
|
||||
|
||||
|
|
@ -36,3 +38,17 @@ register_snippet(RegisterFunction)
|
|||
@register_snippet
|
||||
class RegisterDecorator(models.Model):
|
||||
pass
|
||||
|
||||
|
||||
# A snippet model that inherits from index.Indexed can be searched on
|
||||
|
||||
@register_snippet
|
||||
class SearchableSnippet(models.Model, index.Indexed):
|
||||
text = models.CharField(max_length=255)
|
||||
|
||||
search_fields = (
|
||||
index.SearchField('text'),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.text
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
"model": "wagtailcore.page",
|
||||
"fields": {
|
||||
"title": "Events",
|
||||
"numchild": 4,
|
||||
"numchild": 5,
|
||||
"show_in_menus": true,
|
||||
"live": true,
|
||||
"depth": 3,
|
||||
|
|
@ -86,6 +86,41 @@
|
|||
}
|
||||
},
|
||||
|
||||
{
|
||||
"pk": 13,
|
||||
"model": "wagtailcore.page",
|
||||
"fields": {
|
||||
"title": "Saint Patrick",
|
||||
"numchild": 0,
|
||||
"show_in_menus": true,
|
||||
"live": true,
|
||||
"depth": 4,
|
||||
"content_type": ["tests", "singleeventpage"],
|
||||
"path": "0001000100010005",
|
||||
"url_path": "/home/events/saint-patrick/",
|
||||
"slug": "saint-patrick",
|
||||
"owner": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 13,
|
||||
"model": "tests.eventpage",
|
||||
"fields": {
|
||||
"date_from": "2014-12-25",
|
||||
"audience": "private",
|
||||
"location": "Wellington",
|
||||
"body": "<p>The day when nothing makes sense.</p>",
|
||||
"cost": "Semi-free"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 13,
|
||||
"model": "tests.singleeventpage",
|
||||
"fields": {
|
||||
"excerpt": "A little tiny excerpt for Saint Patrick."
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "tests.eventpagespeaker",
|
||||
|
|
|
|||
24
wagtail/tests/testapp/migrations/0007_auto_20150819_0614.py
Normal file
24
wagtail/tests/testapp/migrations/0007_auto_20150819_0614.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0006_image_file_size'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customimagewithadminformfields',
|
||||
name='created_at',
|
||||
field=models.DateTimeField(db_index=True, verbose_name='Created at', auto_now_add=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customimagewithoutadminformfields',
|
||||
name='created_at',
|
||||
field=models.DateTimeField(db_index=True, verbose_name='Created at', auto_now_add=True),
|
||||
),
|
||||
]
|
||||
22
wagtail/tests/testapp/migrations/0007_singleeventpage.py
Normal file
22
wagtail/tests/testapp/migrations/0007_singleeventpage.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0006_image_file_size'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SingleEventPage',
|
||||
fields=[
|
||||
('eventpage_ptr', models.OneToOneField(auto_created=True, to='tests.EventPage', serialize=False, parent_link=True, primary_key=True)),
|
||||
('excerpt', models.TextField(help_text='Short text to describe what is this action about', max_length=255, null=True, blank=True)),
|
||||
],
|
||||
bases=('tests.eventpage',),
|
||||
),
|
||||
]
|
||||
15
wagtail/tests/testapp/migrations/0008_merge.py
Normal file
15
wagtail/tests/testapp/migrations/0008_merge.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0007_auto_20150819_0614'),
|
||||
('tests', '0007_singleeventpage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue