diff --git a/runtests.py b/runtests.py
index b8f81f20d..4dd047670 100755
--- a/runtests.py
+++ b/runtests.py
@@ -82,6 +82,9 @@ if not settings.configured:
'wagtail.wagtailredirects',
'wagtail.tests',
],
+ PASSWORD_HASHERS=(
+ 'django.contrib.auth.hashers.MD5PasswordHasher', # don't use the intentionally slow default password hasher
+ ),
WAGTAILSEARCH_BACKENDS=WAGTAILSEARCH_BACKENDS,
WAGTAIL_SITE_NAME='Test Site'
)
diff --git a/scripts/install/debian.sh b/scripts/install/debian.sh
new file mode 100644
index 000000000..2b1c04326
--- /dev/null
+++ b/scripts/install/debian.sh
@@ -0,0 +1,129 @@
+# Production-configured Wagtail installation
+# (secure services/account for full production use).
+# Tested on Debian 7.0.
+# Tom Dyson and Neal Todd
+
+# NB: Ensure the system locale is okay before running (dpkg-reconfigure locales).
+
+PROJECT=mywagtail
+PROJECT_ROOT=/usr/local/django
+
+echo "This script overwrites key files, and should only be run on a new box."
+read -p "Type 'yes' to confirm: " CONFIRM
+[ “$CONFIRM” == “yes” ] || exit
+
+read -p "Enter a name for your project [$PROJECT]: " U_PROJECT
+if [ ! -z "$U_PROJECT" ]; then
+ PROJECT=$U_PROJECT
+fi
+
+read -p "Enter the root of your project, without trailing slash [$PROJECT_ROOT]: " U_PROJECT_ROOT
+if [ ! -z "$U_PROJECT_ROOT" ]; then
+ PROJECT_ROOT=$U_PROJECT_ROOT
+fi
+
+if [ ! -z "$PROJECT_ROOT" ]; then
+ mkdir -p $PROJECT_ROOT || exit
+fi
+
+echo -e "\nPlease come back in a few minutes, when we'll need you to create an admin account."
+sleep 5
+
+SERVER_IP=`ifconfig eth0 |grep "inet addr" | cut -d: -f2 | cut -d" " -f1`
+
+aptitude update
+aptitude -y install git python-pip nginx postgresql redis-server
+aptitude -y install postgresql-server-dev-all python-dev libxml2-dev libxslt-dev libjpeg62-dev
+
+wget -nv http://nodejs.org/dist/v0.10.20/node-v0.10.20.tar.gz
+tar xzf node-v0.10.20.tar.gz
+cd node-v0.10.20
+./configure && make -s && make -s install
+cd ..
+rm -r node-v0.10.20 node-v0.10.20.tar.gz
+npm install -g less
+
+perl -pi -e "s/^(local\s+all\s+postgres\s+)peer$/\1trust/" /etc/postgresql/9.1/main/pg_hba.conf
+service postgresql reload
+
+aptitude -y install openjdk-7-jre-headless
+curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.0.deb
+dpkg -i elasticsearch-1.0.0.deb
+rm elasticsearch-1.0.0.deb
+update-rc.d elasticsearch defaults 95 10
+service elasticsearch start
+
+cd $PROJECT_ROOT
+git clone https://github.com/torchbox/wagtaildemo.git $PROJECT
+cd $PROJECT
+mv wagtaildemo $PROJECT
+perl -pi -e"s/wagtaildemo/$PROJECT/" manage.py $PROJECT/wsgi.py $PROJECT/settings/*.py
+rm -r etc README.md Vagrantfile* .git .gitignore
+
+dd if=/dev/zero of=/tmpswap bs=1024 count=524288
+mkswap /tmpswap
+swapon /tmpswap
+pip install -r requirements/production.txt
+swapoff -v /tmpswap
+rm /tmpswap
+
+echo SECRET_KEY = \"`python -c 'import random; print "".join([random.SystemRandom().choice("abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)") for i in range(50)])'`\" > $PROJECT/settings.local.py
+echo ALLOWED_HOSTS = [\'$SERVER_IP\',] >> $PROJECT/settings/local.py
+createdb -Upostgres $PROJECT
+./manage.py syncdb --settings=$PROJECT.settings.production
+./manage.py migrate --settings=$PROJECT.settings.production
+./manage.py update_index --settings=$PROJECT.settings.production
+./manage.py collectstatic --settings=$PROJECT.settings.production --noinput
+
+pip install uwsgi
+cp $PROJECT/wsgi.py $PROJECT/wsgi_production.py
+perl -pi -e"s/($PROJECT.settings)/\1.production/" $PROJECT/wsgi_production.py
+
+curl -O https://raw2.github.com/nginx/nginx/master/conf/uwsgi_params
+cat << EOF > /etc/nginx/sites-enabled/default
+upstream django {
+ server unix://$PROJECT_ROOT/$PROJECT/uwsgi.sock;
+}
+server {
+ listen 80;
+ charset utf-8;
+ client_max_body_size 75M; # max upload size
+ location /media {
+ alias $PROJECT_ROOT/$PROJECT/media;
+ }
+ location /static {
+ alias $PROJECT_ROOT/$PROJECT/static;
+ }
+ location / {
+ uwsgi_pass django;
+ include $PROJECT_ROOT/$PROJECT/uwsgi_params;
+ }
+}
+EOF
+
+cat << EOF > $PROJECT_ROOT/$PROJECT/uwsgi_conf.ini
+[uwsgi]
+chdir = $PROJECT_ROOT/$PROJECT
+module = $PROJECT.wsgi_production
+master = true
+processes = 10
+socket = $PROJECT_ROOT/$PROJECT/uwsgi.sock
+chmod-socket = 666
+vacuum = true
+EOF
+
+mkdir -p /etc/uwsgi/vassals/
+ln -s $PROJECT_ROOT/$PROJECT/uwsgi_conf.ini /etc/uwsgi/vassals/
+
+curl -o /etc/init.d/uwsgi https://raw.github.com/torchbox/wagtail/master/scripts/install/uwsgi-init.d
+mkdir /var/log/uwsgi
+chmod 755 /etc/init.d/uwsgi
+update-rc.d uwsgi defaults
+
+service uwsgi start
+service nginx restart
+
+URL="http://$SERVER_IP"
+echo -e "\n\nWagtail lives!\n\n"
+echo "The public site is at $URL/"
+echo "and the admin interface is at $URL/admin/"
diff --git a/scripts/install/ubuntu.sh b/scripts/install/ubuntu.sh
new file mode 100644
index 000000000..ac38d5910
--- /dev/null
+++ b/scripts/install/ubuntu.sh
@@ -0,0 +1,125 @@
+# Production-configured Wagtail installation
+# (secure services/account for full production use).
+# Tested on Ubuntu 13.10.
+# Tom Dyson and Neal Todd
+
+PROJECT=mywagtail
+PROJECT_ROOT=/usr/local/django
+
+echo "This script overwrites key files, and should only be run on a new box."
+read -p "Type 'yes' to confirm: " CONFIRM
+[ “$CONFIRM” == “yes” ] || exit
+
+read -p "Enter a name for your project [$PROJECT]: " U_PROJECT
+if [ ! -z "$U_PROJECT" ]; then
+ PROJECT=$U_PROJECT
+fi
+
+read -p "Enter the root of your project, without trailing slash [$PROJECT_ROOT]: " U_PROJECT_ROOT
+if [ ! -z "$U_PROJECT_ROOT" ]; then
+ PROJECT_ROOT=$U_PROJECT_ROOT
+fi
+
+if [ ! -z "$PROJECT_ROOT" ]; then
+ mkdir -p $PROJECT_ROOT || exit
+fi
+
+echo -e "\nPlease come back in a few minutes, when we'll need you to create an admin account."
+sleep 5
+
+SERVER_IP=`ifconfig eth0 |grep "inet addr" | cut -d: -f2 | cut -d" " -f1`
+
+aptitude update
+aptitude -y install git python-pip nginx postgresql redis-server
+aptitude -y install postgresql-server-dev-all python-dev libxml2-dev libxslt-dev libjpeg62-dev
+
+aptitude -y install npm
+ln -s /usr/bin/nodejs /usr/bin/node
+npm install -g less
+
+perl -pi -e "s/^(local\s+all\s+postgres\s+)peer$/\1trust/" /etc/postgresql/9.1/main/pg_hba.conf
+service postgresql reload
+
+aptitude -y install openjdk-7-jre-headless
+curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.0.deb
+dpkg -i elasticsearch-1.0.0.deb
+rm elasticsearch-1.0.0.deb
+update-rc.d elasticsearch defaults 95 10
+service elasticsearch start
+
+cd $PROJECT_ROOT
+git clone https://github.com/torchbox/wagtaildemo.git $PROJECT
+cd $PROJECT
+mv wagtaildemo $PROJECT
+perl -pi -e"s/wagtaildemo/$PROJECT/" manage.py $PROJECT/wsgi.py $PROJECT/settings/*.py
+rm -r etc README.md Vagrantfile* .git .gitignore
+
+dd if=/dev/zero of=/tmpswap bs=1024 count=524288
+mkswap /tmpswap
+swapon /tmpswap
+pip install -r requirements/production.txt
+swapoff -v /tmpswap
+rm /tmpswap
+
+echo SECRET_KEY = \"`python -c 'import random; print "".join([random.SystemRandom().choice("abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)") for i in range(50)])'`\" > $PROJECT/settings.local.py
+echo ALLOWED_HOSTS = [\'$SERVER_IP\',] >> $PROJECT/settings/local.py
+createdb -Upostgres $PROJECT
+./manage.py syncdb --settings=$PROJECT.settings.production
+./manage.py migrate --settings=$PROJECT.settings.production
+./manage.py update_index --settings=$PROJECT.settings.production
+./manage.py collectstatic --settings=$PROJECT.settings.production --noinput
+
+pip install uwsgi
+cp $PROJECT/wsgi.py $PROJECT/wsgi_production.py
+perl -pi -e"s/($PROJECT.settings)/\1.production/" $PROJECT/wsgi_production.py
+
+curl -O https://raw2.github.com/nginx/nginx/master/conf/uwsgi_params
+cat << EOF > /etc/nginx/sites-enabled/default
+upstream django {
+ server unix://$PROJECT_ROOT/$PROJECT/uwsgi.sock;
+}
+server {
+ listen 80;
+ charset utf-8;
+ client_max_body_size 75M; # max upload size
+ location /media {
+ alias $PROJECT_ROOT/$PROJECT/media;
+ }
+ location /static {
+ alias $PROJECT_ROOT/$PROJECT/static;
+ }
+ location / {
+ uwsgi_pass django;
+ include $PROJECT_ROOT/$PROJECT/uwsgi_params;
+ }
+}
+EOF
+
+cat << EOF > $PROJECT_ROOT/$PROJECT/uwsgi_conf.ini
+[uwsgi]
+chdir = $PROJECT_ROOT/$PROJECT
+module = $PROJECT.wsgi_production
+master = true
+processes = 10
+socket = $PROJECT_ROOT/$PROJECT/uwsgi.sock
+chmod-socket = 666
+vacuum = true
+EOF
+
+mkdir -p /etc/uwsgi/vassals/
+ln -s $PROJECT_ROOT/$PROJECT/uwsgi_conf.ini /etc/uwsgi/vassals/
+
+cat << EOF > /etc/init/uwsgi.conf
+description "uwsgi for wagtail"
+start on runlevel [2345]
+stop on runlevel [06]
+exec uwsgi --emperor /etc/uwsgi/vassals
+EOF
+
+service uwsgi start
+service nginx restart
+
+URL="http://$SERVER_IP"
+echo -e "\n\nWagtail lives!\n\n"
+echo "The public site is at $URL/"
+echo "and the admin interface is at $URL/admin/"
diff --git a/scripts/install/uwsgi-init.d b/scripts/install/uwsgi-init.d
new file mode 100644
index 000000000..43f0bdb13
--- /dev/null
+++ b/scripts/install/uwsgi-init.d
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+
+### BEGIN INIT INFO
+# Provides: emperor
+# Required-Start: $all
+# Required-Stop: $all
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: uwsgi for wagtail
+# Description: uwsgi for wagtail
+### END INIT INFO
+set -e
+
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+DAEMON=/usr/local/bin/uwsgi
+RUN=/var/run/uwsgi
+CONFIG_DIR=/etc/uwsgi/vassals
+NAME=uwsgi
+DESC=emperor
+OWNER=root
+GROUP=root
+OP=$1
+
+[[ -x $DAEMON ]] || exit 0
+[[ -d $RUN ]] || mkdir $RUN && chown $OWNER.$GROUP $RUN
+
+
+do_pid_check()
+{
+ local PIDFILE=$1
+ [[ -f $PIDFILE ]] || return 0
+ local PID=$(cat $PIDFILE)
+ for p in $(pgrep $NAME); do
+ [[ $p == $PID ]] && return 1
+ done
+ return 0
+}
+
+
+do_start()
+{
+ local PIDFILE=$RUN/$NAME.pid
+ local START_OPTS=" \
+ --emperor $CONFIG_DIR \
+ --pidfile $PIDFILE \
+ --uid $OWNER --gid $GROUP \
+ --daemonize /var/log/$NAME/uwsgi-emperor.log"
+ if do_pid_check $PIDFILE; then
+ $NAME $START_OPTS
+ else
+ echo "Already running!"
+ fi
+}
+
+send_sig()
+{
+ local PIDFILE=$RUN/$NAME.pid
+ set +e
+ [[ -f $PIDFILE ]] && kill $1 $(cat $PIDFILE) > /dev/null 2>&1
+ set -e
+}
+
+wait_and_clean_pidfile()
+{
+ local PIDFILE=$RUN/uwsgi.pid
+ until do_pid_check $PIDFILE; do
+ echo -n "";
+ done
+ rm -f $PIDFILE
+}
+
+do_stop()
+{
+ send_sig -3
+ wait_and_clean_pidfile
+}
+
+do_reload()
+{
+ send_sig -1
+}
+
+case "$OP" in
+ start)
+ echo "Starting $DESC: "
+ do_start
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ do_stop
+ echo "$NAME."
+ ;;
+ reload)
+ echo -n "Reloading $DESC: "
+ do_reload
+ echo "$NAME."
+ ;;
+ restart)
+ echo "Restarting $DESC: "
+ do_stop
+ sleep 1
+ do_start
+ echo "$NAME."
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ echo "Usage: $N {start|stop|restart|reload}">&2
+ exit 1
+ ;;
+esac
+exit 0
\ No newline at end of file
diff --git a/wagtail/tests/fixtures/test.json b/wagtail/tests/fixtures/test.json
index 98db24215..99296f7b2 100644
--- a/wagtail/tests/fixtures/test.json
+++ b/wagtail/tests/fixtures/test.json
@@ -39,7 +39,7 @@
"model": "wagtailcore.page",
"fields": {
"title": "Events",
- "numchild": 1,
+ "numchild": 2,
"show_in_menus": true,
"live": true,
"depth": 3,
@@ -69,7 +69,8 @@
"content_type": ["tests", "eventpage"],
"path": "0001000100010001",
"url_path": "/home/events/christmas/",
- "slug": "christmas"
+ "slug": "christmas",
+ "owner": 2
}
},
{
@@ -84,6 +85,62 @@
}
},
+{
+ "pk": 5,
+ "model": "wagtailcore.page",
+ "fields": {
+ "title": "Tentative Unpublished Event",
+ "numchild": 1,
+ "show_in_menus": true,
+ "live": false,
+ "depth": 4,
+ "content_type": ["tests", "eventpage"],
+ "path": "0001000100010002",
+ "url_path": "/home/events/tentative-unpublished-event/",
+ "slug": "tentative-unpublished-event",
+ "owner": 2
+ }
+},
+{
+ "pk": 5,
+ "model": "tests.eventpage",
+ "fields": {
+ "date_from": "2015-07-04",
+ "audience": "public",
+ "location": "The moon",
+ "body": "
I haven't worked out the details yet, but it's going to have cake and ponies
",
+ "cost": "Free"
+ }
+},
+
+{
+ "pk": 6,
+ "model": "wagtailcore.page",
+ "fields": {
+ "title": "Someone Else's Event",
+ "numchild": 1,
+ "show_in_menus": true,
+ "live": false,
+ "depth": 4,
+ "content_type": ["tests", "eventpage"],
+ "path": "0001000100010003",
+ "url_path": "/home/events/someone-elses-event/",
+ "slug": "someone-elses-event",
+ "owner": 3
+ }
+},
+{
+ "pk": 6,
+ "model": "tests.eventpage",
+ "fields": {
+ "date_from": "2015-07-04",
+ "audience": "private",
+ "location": "The moon",
+ "body": "your name's not down, you're not coming in
",
+ "cost": "Free (but not for you)"
+ }
+},
+
{
"pk": 1,
"model": "wagtailcore.site",
@@ -93,5 +150,140 @@
"port": 80,
"is_default_site": true
}
+},
+
+{
+ "pk": 3,
+ "model": "auth.group",
+ "fields": {
+ "name": "Event editors",
+ "permissions": [
+ ["access_admin", "wagtailadmin", "admin"],
+ ["add_image", "wagtailimages", "image"],
+ ["change_image", "wagtailimages", "image"],
+ ["delete_image", "wagtailimages", "image"]
+ ]
+ }
+},
+{
+ "pk": 4,
+ "model": "auth.group",
+ "fields": {
+ "name": "Event moderators",
+ "permissions": [
+ ["access_admin", "wagtailadmin", "admin"],
+ ["add_image", "wagtailimages", "image"],
+ ["change_image", "wagtailimages", "image"],
+ ["delete_image", "wagtailimages", "image"]
+ ]
+ }
+},
+{
+ "pk": 1,
+ "model": "wagtailcore.grouppagepermission",
+ "fields": {
+ "group": ["Event editors"],
+ "page": 3,
+ "permission_type": "add"
+ }
+},
+{
+ "pk": 2,
+ "model": "wagtailcore.grouppagepermission",
+ "fields": {
+ "group": ["Event moderators"],
+ "page": 3,
+ "permission_type": "add"
+ }
+},
+{
+ "pk": 3,
+ "model": "wagtailcore.grouppagepermission",
+ "fields": {
+ "group": ["Event moderators"],
+ "page": 3,
+ "permission_type": "edit"
+ }
+},
+{
+ "pk": 4,
+ "model": "wagtailcore.grouppagepermission",
+ "fields": {
+ "group": ["Event moderators"],
+ "page": 3,
+ "permission_type": "publish"
+ }
+},
+
+{
+ "pk": 1,
+ "model": "auth.user",
+ "fields": {
+ "username": "superuser",
+ "first_name": "",
+ "last_name": "",
+ "is_active": true,
+ "is_superuser": true,
+ "is_staff": true,
+ "groups": [
+ ],
+ "user_permissions": [],
+ "password": "md5$seasalt$1e9bf2bf5606aa5c39852cc30f0f6f22",
+ "email": "superuser@example.com"
+ }
+},
+{
+ "pk": 2,
+ "model": "auth.user",
+ "fields": {
+ "username": "eventeditor",
+ "first_name": "",
+ "last_name": "",
+ "is_active": true,
+ "is_superuser": false,
+ "is_staff": false,
+ "groups": [
+ ["Event editors"]
+ ],
+ "user_permissions": [],
+ "password": "md5$seasalt$1e9bf2bf5606aa5c39852cc30f0f6f22",
+ "email": "eventeditor@example.com"
+ }
+},
+{
+ "pk": 3,
+ "model": "auth.user",
+ "fields": {
+ "username": "eventmoderator",
+ "first_name": "",
+ "last_name": "",
+ "is_active": true,
+ "is_superuser": false,
+ "is_staff": false,
+ "groups": [
+ ["Event moderators"]
+ ],
+ "user_permissions": [],
+ "password": "md5$seasalt$1e9bf2bf5606aa5c39852cc30f0f6f22",
+ "email": "eventmoderator@example.com"
+ }
+},
+{
+ "pk": 4,
+ "model": "auth.user",
+ "fields": {
+ "username": "inactiveuser",
+ "first_name": "",
+ "last_name": "",
+ "is_active": false,
+ "is_superuser": false,
+ "is_staff": false,
+ "groups": [
+ ["Event moderators"]
+ ],
+ "user_permissions": [],
+ "password": "md5$seasalt$1e9bf2bf5606aa5c39852cc30f0f6f22",
+ "email": "inactiveuser@example.com"
+ }
}
]
diff --git a/wagtail/tests/templates/tests/event_page.html b/wagtail/tests/templates/tests/event_page.html
new file mode 100644
index 000000000..917c83501
--- /dev/null
+++ b/wagtail/tests/templates/tests/event_page.html
@@ -0,0 +1,10 @@
+
+
+
+ Event: {{ self.title }}
+
+
+ {{ self.title }}
+ Event
+
+
diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-hr.coffee b/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-hr.coffee
deleted file mode 100644
index 76eb5a04c..000000000
--- a/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-hr.coffee
+++ /dev/null
@@ -1,28 +0,0 @@
-# Hallo - a rich text editing jQuery UI widget
-# (c) 2011 Henri Bergius, IKS Consortium
-# Hallo may be freely distributed under the MIT license
-((jQuery) ->
- jQuery.widget "IKS.hallohr",
- options:
- editable: null
- toolbar: null
- uuid: ''
- buttonCssClass: null
-
- populateToolbar: (toolbar) ->
- buttonset = jQuery ""
-
- buttonElement = jQuery ''
- buttonElement.hallobutton
- uuid: @options.uuid
- editable: @options.editable
- label: "Horizontal rule"
- command: "insertHorizontalRule"
- icon: "icon-horizontalrule"
- cssClass: @options.buttonCssClass
- buttonset.append buttonElement
-
- buttonset.hallobuttonset()
- toolbar.append buttonset
-
-)(jQuery)
diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-hr.js b/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-hr.js
new file mode 100644
index 000000000..0989d1fc6
--- /dev/null
+++ b/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-hr.js
@@ -0,0 +1,31 @@
+// Generated by CoffeeScript 1.6.2
+(function() {
+ (function(jQuery) {
+ return jQuery.widget("IKS.hallohr", {
+ options: {
+ editable: null,
+ toolbar: null,
+ uuid: '',
+ buttonCssClass: null
+ },
+ populateToolbar: function(toolbar) {
+ var buttonElement, buttonset;
+
+ buttonset = jQuery("");
+ buttonElement = jQuery('');
+ buttonElement.hallobutton({
+ uuid: this.options.uuid,
+ editable: this.options.editable,
+ label: "Horizontal rule",
+ command: "insertHorizontalRule",
+ icon: "icon-horizontalrule",
+ cssClass: this.options.buttonCssClass
+ });
+ buttonset.append(buttonElement);
+ buttonset.hallobuttonset();
+ return toolbar.append(buttonset);
+ }
+ });
+ })(jQuery);
+
+}).call(this);
\ No newline at end of file
diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-wagtaillink.coffee b/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-wagtaillink.coffee
deleted file mode 100644
index fbc405f8a..000000000
--- a/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-wagtaillink.coffee
+++ /dev/null
@@ -1,68 +0,0 @@
-# plugin for hallo.js to allow inserting links using Wagtail's page chooser
-
-(($) ->
- $.widget "IKS.hallowagtaillink",
- options:
- uuid: ''
- editable: null
-
- populateToolbar: (toolbar) ->
- widget = this
-
- getEnclosingLink = () ->
- # if cursor is currently within a link element, return it, otherwise return null
- node = widget.options.editable.getSelection().commonAncestorContainer
- return $(node).parents('a').get(0)
-
- # Create an element for holding the button
- button = $('')
- button.hallobutton
- uuid: @options.uuid
- editable: @options.editable
- label: 'Links'
- icon: 'icon-link'
- command: null
- queryState: (event) ->
- button.hallobutton('checked', !!getEnclosingLink())
-
- # Append the button to toolbar
- toolbar.append button
-
- button.on "click", (event) ->
- enclosingLink = getEnclosingLink()
- if enclosingLink
- # remove existing link
- $(enclosingLink).replaceWith(enclosingLink.innerHTML)
- button.hallobutton('checked', false)
- widget.options.editable.element.trigger('change')
- else
- # commence workflow to add a link
- lastSelection = widget.options.editable.getSelection()
-
- if lastSelection.collapsed
- # TODO: don't hard-code this, as it may be changed in urls.py
- url = window.chooserUrls.pageChooser + '?allow_external_link=true&allow_email_link=true&prompt_for_link_text=true'
- else
- url = window.chooserUrls.pageChooser + '?allow_external_link=true&allow_email_link=true'
-
- ModalWorkflow
- url: url
- responses:
- pageChosen: (pageData) ->
- a = document.createElement('a')
- a.setAttribute('href', pageData.url)
- if pageData.id
- a.setAttribute('data-id', pageData.id)
- a.setAttribute('data-linktype', 'page')
-
- if (not lastSelection.collapsed) and lastSelection.canSurroundContents()
- # use the selected content as the link text
- lastSelection.surroundContents(a)
- else
- # no text is selected, so use the page title as link text
- a.appendChild(document.createTextNode pageData.title)
- lastSelection.insertNode(a)
-
- widget.options.editable.element.trigger('change')
-
-)(jQuery)
diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-wagtaillink.js b/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-wagtaillink.js
new file mode 100644
index 000000000..03732110d
--- /dev/null
+++ b/wagtail/wagtailadmin/static/wagtailadmin/js/hallo-plugins/hallo-wagtaillink.js
@@ -0,0 +1,74 @@
+// Generated by CoffeeScript 1.6.2
+(function() {
+ (function($) {
+ return $.widget("IKS.hallowagtaillink", {
+ options: {
+ uuid: '',
+ editable: null
+ },
+ populateToolbar: function(toolbar) {
+ var button, getEnclosingLink, widget;
+
+ widget = this;
+ getEnclosingLink = function() {
+ var node;
+
+ node = widget.options.editable.getSelection().commonAncestorContainer;
+ return $(node).parents('a').get(0);
+ };
+ button = $('');
+ button.hallobutton({
+ uuid: this.options.uuid,
+ editable: this.options.editable,
+ label: 'Links',
+ icon: 'icon-link',
+ command: null,
+ queryState: function(event) {
+ return button.hallobutton('checked', !!getEnclosingLink());
+ }
+ });
+ toolbar.append(button);
+ return button.on("click", function(event) {
+ var enclosingLink, lastSelection, url;
+
+ enclosingLink = getEnclosingLink();
+ if (enclosingLink) {
+ $(enclosingLink).replaceWith(enclosingLink.innerHTML);
+ button.hallobutton('checked', false);
+ return widget.options.editable.element.trigger('change');
+ } else {
+ lastSelection = widget.options.editable.getSelection();
+ if (lastSelection.collapsed) {
+ url = window.chooserUrls.pageChooser + '?allow_external_link=true&allow_email_link=true&prompt_for_link_text=true';
+ } else {
+ url = window.chooserUrls.pageChooser + '?allow_external_link=true&allow_email_link=true';
+ }
+ return ModalWorkflow({
+ url: url,
+ responses: {
+ pageChosen: function(pageData) {
+ var a;
+
+ a = document.createElement('a');
+ a.setAttribute('href', pageData.url);
+ if (pageData.id) {
+ a.setAttribute('data-id', pageData.id);
+ a.setAttribute('data-linktype', 'page');
+ }
+ if ((!lastSelection.collapsed) && lastSelection.canSurroundContents()) {
+ lastSelection.surroundContents(a);
+ } else {
+ a.appendChild(document.createTextNode(pageData.title));
+ lastSelection.insertNode(a);
+ }
+ return widget.options.editable.element.trigger('change');
+ }
+ }
+ });
+ }
+ });
+ }
+ });
+ })(jQuery);
+
+}).call(this);
\ No newline at end of file
diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/_editor_js.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/_editor_js.html
index 518a2c59b..da2628966 100644
--- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/_editor_js.html
+++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/_editor_js.html
@@ -13,16 +13,16 @@
-
-
-
-
-
+
+
+
+
+
{% comment %}
- TODO: have a mechanism to specify image-chooser.js (and hallo-wagtailimage.coffee)
+ TODO: have a mechanism to specify image-chooser.js (and hallo-wagtailimage.js)
within the wagtailimages app -
ideally wagtailadmin shouldn't have to know anything at all about wagtailimages
TODO: a method of injecting these sorts of things on demand when the modal is spawned.
diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html
index fdbfb19ff..a0faa0da1 100644
--- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html
+++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html
@@ -75,7 +75,7 @@
{{ parent_page.content_type.model_class.get_verbose_name }} |
- {% if not choosing and parent_page.live and not parent_page.is_root and 'view_live' not in hide_actions|default:'' %}
+ {% if not choosing and not moving and parent_page.live and not parent_page.is_root and 'view_live' not in hide_actions|default:'' %}
{{ parent_page.status_string|capfirst }}
{% else %}
{{ parent_page.status_string|capfirst }}
@@ -208,7 +208,7 @@
{% endif %}
| {{ page.content_type.model_class.get_verbose_name }} |
- {% if not choosing and page.live and 'view_live' not in hide_actions|default:'' %}
+ {% if not choosing and not moving and page.live and 'view_live' not in hide_actions|default:'' %}
{{ page.status_string }}
{% else %}
{{ page.status_string }}
diff --git a/wagtail/wagtailcore/models.py b/wagtail/wagtailcore/models.py
index 092752037..90e699808 100644
--- a/wagtail/wagtailcore/models.py
+++ b/wagtail/wagtailcore/models.py
@@ -6,11 +6,11 @@ from modelcluster.models import ClusterableModel
from django.db import models, connection, transaction
from django.db.models import get_model, Q
from django.http import Http404
-from django.shortcuts import render
from django.core.cache import cache
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Group
from django.conf import settings
+from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
from wagtail.wagtailcore.util import camelcase_to_underscore
@@ -326,7 +326,7 @@ class Page(MP_Node, ClusterableModel, Indexed):
return revision.as_page_object()
def serve(self, request):
- return render(request, self.template, {
+ return TemplateResponse(request, self.template, {
'self': self
})
@@ -742,7 +742,7 @@ class PagePermissionTester(object):
def can_move_to(self, destination):
# reject the logically impossible cases first
- if self.page == destination or destination.is_child_of(self.page):
+ if self.page == destination or destination.is_descendant_of(self.page):
return False
# and shortcut the trivial 'everything' / 'nothing' permissions
diff --git a/wagtail/wagtailcore/tests.py b/wagtail/wagtailcore/tests.py
index ccd91d009..58ff51ada 100644
--- a/wagtail/wagtailcore/tests.py
+++ b/wagtail/wagtailcore/tests.py
@@ -1,10 +1,37 @@
-from django.test import TestCase
+from django.test import TestCase, Client
+from django.http import HttpRequest, Http404
+
+from django.contrib.auth.models import User
+
from wagtail.wagtailcore.models import Page, Site
+from wagtail.tests.models import EventPage
class TestRouting(TestCase):
fixtures = ['test.json']
+ def test_find_site_for_request(self):
+ default_site = Site.objects.get(is_default_site=True)
+ events_page = Page.objects.get(url_path='/home/events/')
+ events_site = Site.objects.create(hostname='events.example.com', root_page=events_page)
+
+ # requests without a Host: header should be directed to the default site
+ request = HttpRequest()
+ request.path = '/'
+ self.assertEqual(Site.find_for_request(request), default_site)
+
+ # requests with a known Host: header should be directed to the specific site
+ request = HttpRequest()
+ request.path = '/'
+ request.META['HTTP_HOST'] = 'events.example.com'
+ self.assertEqual(Site.find_for_request(request), events_site)
+
+ # requests with an unrecognised Host: header should be directed to the default site
+ request = HttpRequest()
+ request.path = '/'
+ request.META['HTTP_HOST'] = 'unknown.example.com'
+ self.assertEqual(Site.find_for_request(request), default_site)
+
def test_urls(self):
default_site = Site.objects.get(is_default_site=True)
homepage = Page.objects.get(url_path='/home/')
@@ -38,3 +65,234 @@ class TestRouting(TestCase):
self.assertEqual(christmas_page.url, 'http://events.example.com/christmas/')
self.assertEqual(christmas_page.relative_url(default_site), 'http://events.example.com/christmas/')
self.assertEqual(christmas_page.relative_url(events_site), '/christmas/')
+
+ def test_request_routing(self):
+ homepage = Page.objects.get(url_path='/home/')
+ christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
+
+ request = HttpRequest()
+ request.path = '/events/christmas/'
+ response = homepage.route(request, ['events', 'christmas'])
+
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.context_data['self'], christmas_page)
+ used_template = response.resolve_template(response.template_name)
+ self.assertEqual(used_template.name, 'tests/event_page.html')
+
+ def test_route_to_unknown_page_returns_404(self):
+ homepage = Page.objects.get(url_path='/home/')
+
+ request = HttpRequest()
+ request.path = '/events/quinquagesima/'
+ with self.assertRaises(Http404):
+ homepage.route(request, ['events', 'quinquagesima'])
+
+ def test_route_to_unpublished_page_returns_404(self):
+ homepage = Page.objects.get(url_path='/home/')
+
+ request = HttpRequest()
+ request.path = '/events/tentative-unpublished-event/'
+ with self.assertRaises(Http404):
+ homepage.route(request, ['events', 'tentative-unpublished-event'])
+
+
+class TestServeView(TestCase):
+ fixtures = ['test.json']
+
+ def test_serve(self):
+ response = self.client.get('/events/christmas/')
+
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.templates[0].name, 'tests/event_page.html')
+ christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
+ self.assertEqual(response.context['self'], christmas_page)
+
+ self.assertContains(response, 'Christmas')
+ self.assertContains(response, 'Event')
+
+ def test_serve_unknown_page_returns_404(self):
+ response = self.client.get('/events/quinquagesima/')
+ self.assertEqual(response.status_code, 404)
+
+ def test_serve_unpublished_page_returns_404(self):
+ response = self.client.get('/events/tentative-unpublished-event/')
+ self.assertEqual(response.status_code, 404)
+
+ def test_serve_with_multiple_sites(self):
+ events_page = Page.objects.get(url_path='/home/events/')
+ Site.objects.create(hostname='events.example.com', root_page=events_page)
+
+ response = self.client.get('/christmas/', HTTP_HOST='events.example.com')
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.templates[0].name, 'tests/event_page.html')
+ christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
+ self.assertEqual(response.context['self'], christmas_page)
+
+ self.assertContains(response, 'Christmas')
+ self.assertContains(response, 'Event')
+
+ # same request to the default host should return a 404
+ c = Client()
+ response = c.get('/christmas/', HTTP_HOST='localhost')
+ self.assertEqual(response.status_code, 404)
+
+
+class TestPagePermission(TestCase):
+ fixtures = ['test.json']
+
+ def test_nonpublisher_page_permissions(self):
+ event_editor = User.objects.get(username='eventeditor')
+ homepage = Page.objects.get(url_path='/home/')
+ christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
+ unpublished_event_page = EventPage.objects.get(url_path='/home/events/tentative-unpublished-event/')
+ someone_elses_event_page = EventPage.objects.get(url_path='/home/events/someone-elses-event/')
+
+ homepage_perms = homepage.permissions_for_user(event_editor)
+ christmas_page_perms = christmas_page.permissions_for_user(event_editor)
+ unpub_perms = unpublished_event_page.permissions_for_user(event_editor)
+ someone_elses_event_perms = someone_elses_event_page.permissions_for_user(event_editor)
+
+ self.assertFalse(homepage_perms.can_add_subpage())
+ self.assertTrue(christmas_page_perms.can_add_subpage())
+ self.assertTrue(unpub_perms.can_add_subpage())
+ self.assertTrue(someone_elses_event_perms.can_add_subpage())
+
+ self.assertFalse(homepage_perms.can_edit())
+ self.assertTrue(christmas_page_perms.can_edit())
+ self.assertTrue(unpub_perms.can_edit())
+ self.assertFalse(someone_elses_event_perms.can_edit()) # basic 'add' permission doesn't allow editing pages owned by someone else
+
+ self.assertFalse(homepage_perms.can_delete())
+ self.assertFalse(christmas_page_perms.can_delete()) # cannot delete because it is published
+ self.assertTrue(unpub_perms.can_delete())
+ self.assertFalse(someone_elses_event_perms.can_delete())
+
+ self.assertFalse(homepage_perms.can_publish())
+ self.assertFalse(christmas_page_perms.can_publish())
+ self.assertFalse(unpub_perms.can_publish())
+
+ self.assertFalse(homepage_perms.can_unpublish())
+ self.assertFalse(christmas_page_perms.can_unpublish())
+ self.assertFalse(unpub_perms.can_unpublish())
+
+ self.assertFalse(homepage_perms.can_publish_subpage())
+ self.assertFalse(christmas_page_perms.can_publish_subpage())
+ self.assertFalse(unpub_perms.can_publish_subpage())
+
+ self.assertFalse(homepage_perms.can_reorder_children())
+ self.assertFalse(christmas_page_perms.can_reorder_children())
+ self.assertFalse(unpub_perms.can_reorder_children())
+
+ self.assertFalse(homepage_perms.can_move())
+ self.assertFalse(christmas_page_perms.can_move()) # cannot move because this would involve unpublishing from its current location
+ self.assertTrue(unpub_perms.can_move())
+ self.assertFalse(someone_elses_event_perms.can_move())
+
+ self.assertFalse(christmas_page_perms.can_move_to(unpublished_event_page)) # cannot move because this would involve unpublishing from its current location
+ self.assertTrue(unpub_perms.can_move_to(christmas_page))
+ self.assertFalse(unpub_perms.can_move_to(homepage)) # no permission to create pages at destination
+ self.assertFalse(unpub_perms.can_move_to(unpublished_event_page)) # cannot make page a child of itself
+
+
+ def test_publisher_page_permissions(self):
+ event_moderator = User.objects.get(username='eventmoderator')
+ homepage = Page.objects.get(url_path='/home/')
+ christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
+ unpublished_event_page = EventPage.objects.get(url_path='/home/events/tentative-unpublished-event/')
+
+ homepage_perms = homepage.permissions_for_user(event_moderator)
+ christmas_page_perms = christmas_page.permissions_for_user(event_moderator)
+ unpub_perms = unpublished_event_page.permissions_for_user(event_moderator)
+
+ self.assertFalse(homepage_perms.can_add_subpage())
+ self.assertTrue(christmas_page_perms.can_add_subpage())
+ self.assertTrue(unpub_perms.can_add_subpage())
+
+ self.assertFalse(homepage_perms.can_edit())
+ self.assertTrue(christmas_page_perms.can_edit())
+ self.assertTrue(unpub_perms.can_edit())
+
+ self.assertFalse(homepage_perms.can_delete())
+ self.assertTrue(christmas_page_perms.can_delete()) # cannot delete because it is published
+ self.assertTrue(unpub_perms.can_delete())
+
+ self.assertFalse(homepage_perms.can_publish())
+ self.assertTrue(christmas_page_perms.can_publish())
+ self.assertTrue(unpub_perms.can_publish())
+
+ self.assertFalse(homepage_perms.can_unpublish())
+ self.assertTrue(christmas_page_perms.can_unpublish())
+ self.assertFalse(unpub_perms.can_unpublish()) # cannot unpublish a page that isn't published
+
+ self.assertFalse(homepage_perms.can_publish_subpage())
+ self.assertTrue(christmas_page_perms.can_publish_subpage())
+ self.assertTrue(unpub_perms.can_publish_subpage())
+
+ self.assertFalse(homepage_perms.can_reorder_children())
+ self.assertTrue(christmas_page_perms.can_reorder_children())
+ self.assertTrue(unpub_perms.can_reorder_children())
+
+ self.assertFalse(homepage_perms.can_move())
+ self.assertTrue(christmas_page_perms.can_move())
+ self.assertTrue(unpub_perms.can_move())
+
+ self.assertTrue(christmas_page_perms.can_move_to(unpublished_event_page))
+ self.assertTrue(unpub_perms.can_move_to(christmas_page))
+ self.assertFalse(unpub_perms.can_move_to(homepage)) # no permission to create pages at destination
+ self.assertFalse(unpub_perms.can_move_to(unpublished_event_page)) # cannot make page a child of itself
+
+ def test_inactive_user_has_no_permissions(self):
+ user = User.objects.get(username='inactiveuser')
+ christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
+ unpublished_event_page = EventPage.objects.get(url_path='/home/events/tentative-unpublished-event/')
+
+ christmas_page_perms = christmas_page.permissions_for_user(user)
+ unpub_perms = unpublished_event_page.permissions_for_user(user)
+
+ self.assertFalse(unpub_perms.can_add_subpage())
+ self.assertFalse(unpub_perms.can_edit())
+ self.assertFalse(unpub_perms.can_delete())
+ self.assertFalse(unpub_perms.can_publish())
+ self.assertFalse(christmas_page_perms.can_unpublish())
+ self.assertFalse(unpub_perms.can_publish_subpage())
+ self.assertFalse(unpub_perms.can_reorder_children())
+ self.assertFalse(unpub_perms.can_move())
+ self.assertFalse(unpub_perms.can_move_to(christmas_page))
+
+ def test_superuser_has_full_permissions(self):
+ user = User.objects.get(username='superuser')
+ homepage = Page.objects.get(url_path='/home/')
+ root = Page.objects.get(url_path='/')
+ unpublished_event_page = EventPage.objects.get(url_path='/home/events/tentative-unpublished-event/')
+
+ homepage_perms = homepage.permissions_for_user(user)
+ root_perms = root.permissions_for_user(user)
+ unpub_perms = unpublished_event_page.permissions_for_user(user)
+
+ self.assertTrue(homepage_perms.can_add_subpage())
+ self.assertTrue(root_perms.can_add_subpage())
+
+ self.assertTrue(homepage_perms.can_edit())
+ self.assertFalse(root_perms.can_edit()) # root is not a real editable page, even to superusers
+
+ self.assertTrue(homepage_perms.can_delete())
+ self.assertFalse(root_perms.can_delete())
+
+ self.assertTrue(homepage_perms.can_publish())
+ self.assertFalse(root_perms.can_publish())
+
+ self.assertTrue(homepage_perms.can_unpublish())
+ self.assertFalse(root_perms.can_unpublish())
+ self.assertFalse(unpub_perms.can_unpublish())
+
+ self.assertTrue(homepage_perms.can_publish_subpage())
+ self.assertTrue(root_perms.can_publish_subpage())
+
+ self.assertTrue(homepage_perms.can_reorder_children())
+ self.assertTrue(root_perms.can_reorder_children())
+
+ self.assertTrue(homepage_perms.can_move())
+ self.assertFalse(root_perms.can_move())
+
+ self.assertTrue(homepage_perms.can_move_to(root))
+ self.assertFalse(homepage_perms.can_move_to(unpublished_event_page))
diff --git a/wagtail/wagtaildocs/static/wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.coffee b/wagtail/wagtaildocs/static/wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.coffee
deleted file mode 100644
index 7e961444d..000000000
--- a/wagtail/wagtaildocs/static/wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.coffee
+++ /dev/null
@@ -1,45 +0,0 @@
-# plugin for hallo.js to allow inserting links using Wagtail's page chooser
-
-(($) ->
- $.widget "IKS.hallowagtaildoclink",
- options:
- uuid: ''
- editable: null
-
- populateToolbar: (toolbar) ->
- widget = this
-
- # Create an element for holding the button
- button = $('')
- button.hallobutton
- uuid: @options.uuid
- editable: @options.editable
- label: 'Documents'
- icon: 'icon-file-text-alt'
- command: null
-
- # Append the button to toolbar
- toolbar.append button
-
- button.on "click", (event) ->
- lastSelection = widget.options.editable.getSelection()
- ModalWorkflow
- url: window.chooserUrls.documentChooser
- responses:
- documentChosen: (docData) ->
- a = document.createElement('a')
- a.setAttribute('href', docData.url)
- a.setAttribute('data-id', docData.id)
- a.setAttribute('data-linktype', 'document')
-
- if (not lastSelection.collapsed) and lastSelection.canSurroundContents()
- # use the selected content as the link text
- lastSelection.surroundContents(a)
- else
- # no text is selected, so use the doc title as link text
- a.appendChild(document.createTextNode docData.title)
- lastSelection.insertNode(a)
-
- widget.options.editable.element.trigger('change')
-
-)(jQuery)
diff --git a/wagtail/wagtaildocs/static/wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js b/wagtail/wagtaildocs/static/wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js
new file mode 100644
index 000000000..8f713a711
--- /dev/null
+++ b/wagtail/wagtaildocs/static/wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js
@@ -0,0 +1,51 @@
+// Generated by CoffeeScript 1.6.2
+(function() {
+ (function($) {
+ return $.widget("IKS.hallowagtaildoclink", {
+ options: {
+ uuid: '',
+ editable: null
+ },
+ populateToolbar: function(toolbar) {
+ var button, widget;
+
+ widget = this;
+ button = $('');
+ button.hallobutton({
+ uuid: this.options.uuid,
+ editable: this.options.editable,
+ label: 'Documents',
+ icon: 'icon-file-text-alt',
+ command: null
+ });
+ toolbar.append(button);
+ return button.on("click", function(event) {
+ var lastSelection;
+
+ lastSelection = widget.options.editable.getSelection();
+ return ModalWorkflow({
+ url: window.chooserUrls.documentChooser,
+ responses: {
+ documentChosen: function(docData) {
+ var a;
+
+ a = document.createElement('a');
+ a.setAttribute('href', docData.url);
+ a.setAttribute('data-id', docData.id);
+ a.setAttribute('data-linktype', 'document');
+ if ((!lastSelection.collapsed) && lastSelection.canSurroundContents()) {
+ lastSelection.surroundContents(a);
+ } else {
+ a.appendChild(document.createTextNode(docData.title));
+ lastSelection.insertNode(a);
+ }
+ return widget.options.editable.element.trigger('change');
+ }
+ }
+ });
+ });
+ }
+ });
+ })(jQuery);
+
+}).call(this);
\ No newline at end of file
diff --git a/wagtail/wagtailembeds/static/wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.coffee b/wagtail/wagtailembeds/static/wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.coffee
deleted file mode 100644
index 99e844f8d..000000000
--- a/wagtail/wagtailembeds/static/wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.coffee
+++ /dev/null
@@ -1,36 +0,0 @@
-# plugin for hallo.js to allow inserting embeds
-
-(($) ->
- $.widget "IKS.hallowagtailembeds",
- options:
- uuid: ''
- editable: null
-
- populateToolbar: (toolbar) ->
- widget = this
-
- # Create an element for holding the button
- button = $('')
- button.hallobutton
- uuid: @options.uuid
- editable: @options.editable
- label: 'Embed'
- icon: 'icon-media'
- command: null
-
- # Append the button to toolbar
- toolbar.append button
-
- button.on "click", (event) ->
- lastSelection = widget.options.editable.getSelection()
- insertionPoint = $(lastSelection.endContainer).parentsUntil('.richtext').last()
- ModalWorkflow
- url: window.chooserUrls.embedsChooser
- responses:
- embedChosen: (embedData) ->
- elem = $(embedData).get(0)
- lastSelection.insertNode(elem)
- if elem.getAttribute('contenteditable') == 'false'
- insertRichTextDeleteControl(elem)
- widget.options.editable.element.trigger('change')
-)(jQuery)
diff --git a/wagtail/wagtailembeds/static/wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.js b/wagtail/wagtailembeds/static/wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.js
new file mode 100644
index 000000000..eb9f1e05a
--- /dev/null
+++ b/wagtail/wagtailembeds/static/wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.js
@@ -0,0 +1,47 @@
+// Generated by CoffeeScript 1.6.2
+(function() {
+ (function($) {
+ return $.widget("IKS.hallowagtailembeds", {
+ options: {
+ uuid: '',
+ editable: null
+ },
+ populateToolbar: function(toolbar) {
+ var button, widget;
+
+ widget = this;
+ button = $('');
+ button.hallobutton({
+ uuid: this.options.uuid,
+ editable: this.options.editable,
+ label: 'Embed',
+ icon: 'icon-media',
+ command: null
+ });
+ toolbar.append(button);
+ return button.on("click", function(event) {
+ var insertionPoint, lastSelection;
+
+ lastSelection = widget.options.editable.getSelection();
+ insertionPoint = $(lastSelection.endContainer).parentsUntil('.richtext').last();
+ return ModalWorkflow({
+ url: window.chooserUrls.embedsChooser,
+ responses: {
+ embedChosen: function(embedData) {
+ var elem;
+
+ elem = $(embedData).get(0);
+ lastSelection.insertNode(elem);
+ if (elem.getAttribute('contenteditable') === 'false') {
+ insertRichTextDeleteControl(elem);
+ }
+ return widget.options.editable.element.trigger('change');
+ }
+ }
+ });
+ });
+ }
+ });
+ })(jQuery);
+
+}).call(this);
\ No newline at end of file
diff --git a/wagtail/wagtailimages/static/wagtailimages/js/hallo-plugins/hallo-wagtailimage.coffee b/wagtail/wagtailimages/static/wagtailimages/js/hallo-plugins/hallo-wagtailimage.coffee
deleted file mode 100644
index 4a4bcaf7a..000000000
--- a/wagtail/wagtailimages/static/wagtailimages/js/hallo-plugins/hallo-wagtailimage.coffee
+++ /dev/null
@@ -1,39 +0,0 @@
-# plugin for hallo.js to allow inserting images from the Wagtail image library
-
-(($) ->
- $.widget "IKS.hallowagtailimage",
- options:
- uuid: ''
- editable: null
-
- populateToolbar: (toolbar) ->
- widget = this
-
- # Create an element for holding the button
- button = $('')
- button.hallobutton
- uuid: @options.uuid
- editable: @options.editable
- label: 'Images'
- icon: 'icon-picture'
- command: null
-
- # Append the button to toolbar
- toolbar.append button
-
- button.on "click", (event) ->
- lastSelection = widget.options.editable.getSelection()
- insertionPoint = $(lastSelection.endContainer).parentsUntil('.richtext').last()
- ModalWorkflow
- url: window.chooserUrls.imageChooser + '?select_format=true'
- responses:
- imageChosen: (imageData) ->
- elem = $(imageData.html).get(0)
-
- lastSelection.insertNode(elem)
-
- if elem.getAttribute('contenteditable') == 'false'
- insertRichTextDeleteControl(elem)
- widget.options.editable.element.trigger('change')
-
-)(jQuery)
diff --git a/wagtail/wagtailimages/static/wagtailimages/js/hallo-plugins/hallo-wagtailimage.js b/wagtail/wagtailimages/static/wagtailimages/js/hallo-plugins/hallo-wagtailimage.js
new file mode 100644
index 000000000..a0c9bb14b
--- /dev/null
+++ b/wagtail/wagtailimages/static/wagtailimages/js/hallo-plugins/hallo-wagtailimage.js
@@ -0,0 +1,47 @@
+// Generated by CoffeeScript 1.6.2
+(function() {
+ (function($) {
+ return $.widget("IKS.hallowagtailimage", {
+ options: {
+ uuid: '',
+ editable: null
+ },
+ populateToolbar: function(toolbar) {
+ var button, widget;
+
+ widget = this;
+ button = $('');
+ button.hallobutton({
+ uuid: this.options.uuid,
+ editable: this.options.editable,
+ label: 'Images',
+ icon: 'icon-picture',
+ command: null
+ });
+ toolbar.append(button);
+ return button.on("click", function(event) {
+ var insertionPoint, lastSelection;
+
+ lastSelection = widget.options.editable.getSelection();
+ insertionPoint = $(lastSelection.endContainer).parentsUntil('.richtext').last();
+ return ModalWorkflow({
+ url: window.chooserUrls.imageChooser + '?select_format=true',
+ responses: {
+ imageChosen: function(imageData) {
+ var elem;
+
+ elem = $(imageData.html).get(0);
+ lastSelection.insertNode(elem);
+ if (elem.getAttribute('contenteditable') === 'false') {
+ insertRichTextDeleteControl(elem);
+ }
+ return widget.options.editable.element.trigger('change');
+ }
+ }
+ });
+ });
+ }
+ });
+ })(jQuery);
+
+}).call(this);
\ No newline at end of file
|