Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add render_js for easy usage replace of render_esi #10

Closed
alexander-schranz opened this issue Aug 29, 2018 · 1 comment
Closed

Add render_js for easy usage replace of render_esi #10

alexander-schranz opened this issue Aug 29, 2018 · 1 comment
Labels

Comments

@alexander-schranz
Copy link
Member

alexander-schranz commented Aug 29, 2018

Sometimes you want to replace a render_esi with a ajax request.

        <service id="app.renderer.js" class="AppBundle\Fragment\JsFragmentRenderer">
            <argument type="service" id="app.twig.web_component"/>
            <argument type="service" id="uri_signer"/>

            <tag name="kernel.fragment_renderer" alias="js"/>
        </service>
<?php

namespace AppBundle\Fragment;

use Massive\Component\Web\ComponentTwigExtension;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ControllerReference;
use Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer;
use Symfony\Component\HttpKernel\UriSigner;

/**
 * Register and render the div for ajax-include component.
 */
class JsFragmentRenderer extends RoutableFragmentRenderer
{
    /**
     * @var ComponentTwigExtension
     */
    private $webComponentTwigExtension;

    /**
     * @var UriSigner
     */
    private $signer;

    /**
     * JsFragmentRenderer constructor.
     *
     * @param ComponentTwigExtension $webComponentTwigExtension
     * @param UriSigner $signer
     */
    public function __construct(
        ComponentTwigExtension $webComponentTwigExtension,
        UriSigner $signer
    ) {
        $this->webComponentTwigExtension = $webComponentTwigExtension;
        $this->signer = $signer;
    }

    /**
     * {@inheritdoc}
     */
    public function render($uri, Request $request, array $options = [])
    {
        if ($uri instanceof ControllerReference) {
            if (null === $this->signer) {
                throw new \LogicException(
                    'You must use a proper URI when using the JS rendering strategy or set a URL signer.'
                );
            }

            $fragmentUri = $this->generateFragmentUri($uri, $request, true);
            if (!parse_url($fragmentUri)) {
                // FIXME sulu-preview can not generate a property URL. This if can be removed when it is fixed there.

                return new Response('');
            }

            // we need to sign the absolute URI, but want to return the path only.
            $uri = substr($this->signer->sign($fragmentUri), strlen($request->getSchemeAndHttpHost()));
        }

        $id = $this->webComponentTwigExtension->registerComponent('ajax-include', ['uri' => $uri]);

        return new Response(
            sprintf('<div id="%s" data-src="%s"></div>', $id, $uri)
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'js';
    }
}
import ajaxCache from './../services/ajax-cache';

/**
 * @param {String} [options.uri] Define the uri which is requested.
 */
export default {

    uri: null,

    /**
     * @method initialize
     */
    initialize: function($el, options) {
        this.$el = $el;
        this.options = options;
        this.uri = this.options.uri;
        this.refresh();
    },

    refresh: function() {
        ajaxCache.load(this.uri).done(function(data) {
            this.updateContent(data);
        }.bind(this));
    },

    updateContent: function(content) {
        this.$el.html(content);
    }
};
import api from 'massive-web/src/services/api';

export default (function() {
    var cache = {};

    return {
        load: function(uri) {
            if (cache[uri]) {
                return cache[uri];
            }

            return cache[uri] = api.get(uri);
        }
    };
})();
@alexander-schranz
Copy link
Member Author

alexander-schranz commented Sep 25, 2023

While the JS part make sense and we should have a deep look into the component @martinlagler created in Kuegö project as it supports also lazy loading. The twig part is not required as we can use the fragment_uri twig extension instead e.g.:

<div id="{{ prepare_component('ajax-include') }}" data-uri="{{ fragment_uri(controller(...)) }}" aria-busy="true">

</div>

This way we don't have to maintain a fragment handler and the web-twig don't require additional symfony components and stays twig specific.

https://symfony.com/doc/current/reference/twig_reference.html#fragment-uri

/cc @Prokyonn @wachterjohannes

WebJS Issue: sulu/web-js#78

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant