Dynamically updating global page changes

I would like to experiment with a feature for a website. Suppose there is a frontend script which has interactive features (changing colors of some divs, or changing some text for example). I would like to apply those changes not only locally, but to the content files on the server.

Bonus: I would love these changes to be dynamically fetched, so that each time any user updates the website, it is changed for all active users currently looking at the site.

For the first approach, I could probably impersonate the Kirby user similar to what is described here https://getkirby.com/docs/cookbook/forms/creating-pages-from-frontend
and each time the page is refreshed, the latest changes will be loaded.

The more complicated part would be the dynamic updating of the website. I have heard of https://socket.io/ but never used it. It works with node.js and express. My current take on the idea would be to create a socket app on a different server and embed it on the original website… Maybe somebody has experience with something similar and could help me how to integrate it on a Kirby site? :sailboat:

I would suggest to look at Vue.js.
This framework allows you to declaratively render data to the DOM.

<div id="app">
  {{ message }}
</div>

To send the data you’ll just need a little script:

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

Of course you can send any data, style, etc… to the DOM.

I’m not sure if Kirby is the best solution for this project. I’ld go with MongoDB, Vue and Express.

thanks for the answer!

shamefully i still haven’t had time to properly look into Vue. It’s definitely on my bucket list, maybe this could be a good time… but also maybe for this purpose a frontend framework is a bit much :confused:

It’s a part of an existing Kirby site that would need to include the app.

I’m trying to set up a docker container with express, socket. io and mongo to host it, and if I succeed, I’ll probably just include it as an iframe on the destination page…

Hm, alright. Well, you can also check out how the Likes Plugin works; if you want to store data just by clicking.

1 Like

ah, nice! thanks for the tip, i will have a look :~) maybe this will be enough for now, because

phew, i’m really not a backend person…

I’ve had some success with building a socket-io app, but soon enough came to realize I totally don’t need to have a live-updating element on the page. So I’ve had a look at the Likes Plugin and Kirby routes in general. Taking some inspiration here’s what I’m working on:

<?php

function setColor($part, $col) {
    $page = site()->find('haus');
    $hausParts = [
        'door',
        'roof',
        'window'
    ];
    if (in_array($part, $hausParts)) {
        kirby()->impersonate('kirby');
        try {
            $page->update([
                $part => $col
            ]);
            return [$part, $col];
        } catch(Exception $e) {
            return $e->getMessage();
        }
    };
}

Kirby::plugin('bruno/haus', [
    'routes' => [
        [
            'pattern' => ['(:any)/setcolor(:all)', 'setcolor/(:all)'],
            'method' => 'POST',
            'action' => function() {
                $part = 'roof';
                $col = 'green';
                $result = setColor($part, $col);
                return Response::json([$result]);
            }
        ]
    ]
]);

It’s not pretty but it works, I can update the page from the frontend via javascript fetch.

Currently the variables are hardcoded, because I’m not sure how to read a request body in a custom route, so my last plan was to append query parameters to the URL that is being fetched via frontend script (something like mysite.com/setcolor?roof=red), read them in the custom route and update the page accordingly.

Why I’m posting about this now is: If there’s three different buttons on my site that should each update a different value of the page, and the user wildly smashes all three buttons many times, it will currently send a lot of requests which is not desirable.
A better approach would obviously be to collect all necessary information in an array until the user stops smashing, and THEN make the request after a short timeout.

I’m wondering how I can rewrite my plugin accordingly. Can you pass an array to $page->update(), and how would I pass this array from the frontend to the plugin?

I saw that it’s possible with the existing Kirby API: https://getkirby.com/docs/reference/api/pages/update but it requires authentication, which in turn requires a set cookie (if i’m not mistaken) and I would like to avoid that.