diff --git a/src/pat/push/documentation.md b/src/pat/push/documentation.md
new file mode 100644
index 000000000..13ebb75bf
--- /dev/null
+++ b/src/pat/push/documentation.md
@@ -0,0 +1,10 @@
+# Description
+
+When an element is equipped with class="pat-push" and a push ID it will listen to, then it will simply refresh the contents of the element.
+
+
+ Messages 1
+
+
diff --git a/src/pat/push/index-push-content.html b/src/pat/push/index-push-content.html
new file mode 100644
index 000000000..a8eabab5a
--- /dev/null
+++ b/src/pat/push/index-push-content.html
@@ -0,0 +1 @@
+messages 5
diff --git a/src/pat/push/index.html b/src/pat/push/index.html
new file mode 100644
index 000000000..2302236a0
--- /dev/null
+++ b/src/pat/push/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+ Injection pattern
+
+
+
+
+
+
+
Push examples
+
+
+ The examples here listen to push events on the body which are thrown by the push_kit service.
+ The push_kit service subscribes to the push_marker topic (currently hard-coded) on an exchange and address as configured in the meta tags.
+ This is: ws://localhost:15674/ws/exchange/quaive.
+ If a message is sent through rabbitmq on the "quaive" exchange type on the push_marker topic containing the message "message_counter" or "message_counter2" the messages badge below will be updated.
+
+
+
+
push-id: message_counter
+
+ Messages 1
+
+
+
+
push-id: message_counter2
+
+ messages 1
+
+
+
+
diff --git a/src/pat/push/push.js b/src/pat/push/push.js
new file mode 100644
index 000000000..94c749156
--- /dev/null
+++ b/src/pat/push/push.js
@@ -0,0 +1,43 @@
+define(
+ ["jquery", "pat-base", "pat-parser", "pat-logger"],
+ function ($, Base, Parser, logging) {
+
+ var log = logging.getLogger("push");
+ var parser = new Parser("push");
+
+ parser.addArgument("url", null);
+ parser.addArgument("push-id", null);
+
+ return Base.extend({
+ name: "push",
+ trigger: ".pat-push",
+
+ init: function ($el, opts) {
+ this.options = parser.parse($el, opts);
+ $(document.body).on("push", function (e, data) {
+ console.log('received push marker');
+ if (data === this.options.pushId) {
+ this.perform_inject();
+ }
+ }.bind(this));
+ },
+
+ perform_inject: function() {
+ let el = this.$el[0];
+ $.ajax({
+ cache: false,
+ dataType: "html",
+ url: this.options.url,
+ })
+ .done((data) => {
+ el.innerHTML = data;
+ })
+ .fail(() => {
+ logger.error("Could not fetch from " + this.options.url + " on push-id " + this.options.pushId);
+ });
+ },
+
+ });
+});
+
+
diff --git a/src/pat/push/tools/.gitignore b/src/pat/push/tools/.gitignore
new file mode 100644
index 000000000..681a17b5b
--- /dev/null
+++ b/src/pat/push/tools/.gitignore
@@ -0,0 +1,3 @@
+bin/
+lib/
+pyvenv.cfg
diff --git a/src/pat/push/tools/README.md b/src/pat/push/tools/README.md
new file mode 100644
index 000000000..5e537b06b
--- /dev/null
+++ b/src/pat/push/tools/README.md
@@ -0,0 +1,19 @@
+# Push tools
+
+Here are some tools to help you test the push pattern.
+
+1) Bootstrap a python environment in the tools directory:
+ ``./initpython.sh``
+
+2) Start the rabbitmq docker container for the first time with ``rabbitmq_start.sh``.
+ After that you can run the docker container with ``docker start rabbitmq``.
+
+3) Start the webpack dev server with ``yarn start`` in the root of the Patternslib directory.
+
+4) Navigate to: ``http://0.0.0.0:3001/src/pat/push/index.html``
+
+5) Send some messages to rabbitmq to update the message counters on the test page:
+ ``./bin/python send.py push_marker message_counter``
+ and
+ ``./bin/python send.py push_marker message_counter2``
+
diff --git a/src/pat/push/tools/initpython.sh b/src/pat/push/tools/initpython.sh
new file mode 100755
index 000000000..d85e24711
--- /dev/null
+++ b/src/pat/push/tools/initpython.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+virtualenv .
+./bin/pip install pika
+
diff --git a/src/pat/push/tools/rabbitmq_enabled_plugins b/src/pat/push/tools/rabbitmq_enabled_plugins
new file mode 100644
index 000000000..2c610642f
--- /dev/null
+++ b/src/pat/push/tools/rabbitmq_enabled_plugins
@@ -0,0 +1 @@
+[rabbitmq_management,rabbitmq_web_stomp].
diff --git a/src/pat/push/tools/rabbitmq_start.sh b/src/pat/push/tools/rabbitmq_start.sh
new file mode 100755
index 000000000..553cac36a
--- /dev/null
+++ b/src/pat/push/tools/rabbitmq_start.sh
@@ -0,0 +1,15 @@
+# https://hub.docker.com/_/rabbitmq
+# docker exec -it rabbitmq /bin/bash
+# docker logs -f rabbitmq
+docker run\
+ -d\
+ --hostname rabbitmq\
+ --name rabbitmq\
+ -p 5672:5672\
+ -p 15672:15672\
+ -p 15674:15674\
+ -e RABBITMQ_DEFAULT_USER=admin\
+ -e RABBITMQ_DEFAULT_PASS=admin\
+ --mount type=bind,source="$(pwd)"/enabled_plugins,target=/etc/rabbitmq/enabled_plugins\
+ rabbitmq:management
+
diff --git a/src/pat/push/tools/send.py b/src/pat/push/tools/send.py
new file mode 100644
index 000000000..ee1bb5709
--- /dev/null
+++ b/src/pat/push/tools/send.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+import pika
+import sys
+
+EXCHANGE = "quaive"
+
+
+if len(sys.argv) < 2:
+ print("Usage:")
+ print(" python send.py ROUTING_KEY MESSAGE")
+ print("Example:")
+ print(" python send.py push_marker content_updated")
+ sys.exit()
+
+
+credentials = pika.PlainCredentials("admin", "admin")
+connection = pika.BlockingConnection(
+ pika.ConnectionParameters(host="localhost", credentials=credentials)
+)
+channel = connection.channel()
+channel.exchange_declare(exchange=EXCHANGE, exchange_type="topic")
+
+routing_key = sys.argv[1]
+message = " ".join(sys.argv[2:])
+
+channel.basic_publish(exchange=EXCHANGE, routing_key=routing_key, body=message)
+
+print(" [x] Sent %r:%r" % (routing_key, message))
+connection.close()
diff --git a/src/patterns.js b/src/patterns.js
index 798b8ebac..77353ebfc 100644
--- a/src/patterns.js
+++ b/src/patterns.js
@@ -52,6 +52,7 @@ define([
"pat-notification",
"pat-masonry",
"pat-placeholder",
+ "pat-push",
"pat-scroll",
"pat-scroll-box",
"pat-selectbox",
diff --git a/webpack/base.config.js b/webpack/base.config.js
index e6103b517..e851a1f0c 100644
--- a/webpack/base.config.js
+++ b/webpack/base.config.js
@@ -36,7 +36,7 @@ module.exports = {
module: {
rules: [
{
- test: /(bumper|patterns|calendar|display-time|equaliser|focus|masonry|push_kit|scroll|scroll-box|tooltip-ng)\.js$/,
+ test: /(bumper|patterns|calendar|display-time|equaliser|focus|masonry|push|push_kit|scroll|scroll-box|tooltip-ng)\.js$/,
loader: 'babel-loader',
query: {
presets: [["@babel/env", {
@@ -223,6 +223,7 @@ module.exports = {
"pat-navigation": path.resolve(__dirname, "../src/pat/navigation/navigation.js"),
"pat-notification": path.resolve(__dirname, "../src/pat/notification/notification.js"),
"pat-placeholder": path.resolve(__dirname, "../src/pat/placeholder/placeholder.js"),
+ "pat-push": path.resolve(__dirname, "../src/pat/push/push.js"),
"pat-selectbox": path.resolve(__dirname, "../src/pat/selectbox/selectbox.js"),
"pat-skeleton": path.resolve(__dirname, "../src/pat/skeleton/skeleton.js"),
"pat-slides": path.resolve(__dirname, "../src/pat/slides/slides.js"),