symfony / webpack-encore-bundle

Symfony integration with Webpack Encore!
https://symfony.com/webpack-encore
MIT License
929 stars 84 forks source link

Absolute url for encore_entry_link_tags and encore_entry_script_tags #19

Open dariogrd opened 5 years ago

dariogrd commented 5 years ago

Hello,

I think it would be interesting if I could pass to encore_entry_link_tags and encore_entry_script_tags functions that I want to generate tags with absolute url. Now, if I want to get absolute url, I can't use encore_entry_link_tags and encore_entry_script_tags.

benr77 commented 5 years ago

+1 for this. I'm generating PDF documents, and the CSS is broken due to the asset URLs being relative instead of absolute.

dariogrd commented 5 years ago

yes, I also need absolute url for generating PDFs

NullIsNot0 commented 5 years ago

Read the last part of README.md file:

If you want more control, you can use the encore_entry_js_files() and encore_entry_css_files() methods to get the list of files needed, then loop and create the script and link tags manually.

Of course, it would be better if encore_entry_link_tags() and encore_entry_script_tags provided functionality to generate relative or absolute paths, but the solution above is a workaround for now.

taner-dll commented 5 years ago

need for generating PDFs.

weaverryan commented 5 years ago

Hmm, yes, I think this feature makes sense. Probably I would recommend 2 new functions:

I believe we would just need to use the request_stack to fetch the master request then prefix the paths with $request->getSchemeAndHttpHost() (if they are not already absolute). For reference, I'm looking how this works for absolute_url() (https://github.com/symfony/symfony/blob/5aa0967f9f0ab803ededefb040d48a0ebc7a27a6/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php#L58) - but the vast majority of that doesn't apply (we can expect that there is a master request, and we know the URLs, for example, will have a starting / by the time they get this far.

MrMitch commented 5 years ago

I'm also in favor of that. My use case is the same as @benr77, i'm generating PDF files from HTML files and the pdf generator (https://github.com/GoogleChrome/puppeteer) needs absolute urls to proprely load the stylesheets.

I was about to create an issue on the symfony/webpack-encore when i remembered that the encore_entry_*_tags are provided by this bundle and not webpack-encore itself.

At the moment, i'm working around this by using a custom macro that relies on the *`encoreentry_files**,assetandabsolute_url` functions :

{% macro encore_absolute_link_tags(entry_point) %}
    {% for file in encore_entry_css_files(entry_point) %}
        <link href="{{ absolute_url(asset(file)) }}" rel="stylesheet" />
    {% endfor %}
{% endmacro %}

(I see @weaverryan and I had the same idea regarding the naming)

This only works for stylesheets (my only need so-far) but another macro with the same logic could be added to also support absolute urls for <script> tags.

Havign this built-into the bundle would be really great !

firomero commented 5 years ago

this macro is not working to me, it doesn't return the files. Maybe the version I am using. Symfony4.2 trying to deploy on Apache. There is another way?

MrMitch commented 5 years ago

@firomero this is likely because you already use the entry_entry_*_files functions elsewhere before. Take a look at https://github.com/symfony/webpack-encore-bundle/issues/33 which explains this situation in a bit more details.

max4kaps commented 5 years ago

same here. @MrMitch: I used your code.

Did a trick for me. Hier is addition for scripts:

{% macro encore_absolute_link_tags(entry_point) %}
    {% for file in encore_entry_css_files(entry_point) %}
        <link href="{{ absolute_url(asset(file)) }}" rel="stylesheet" />
    {% endfor %}
{% endmacro %}

{% macro encore_absolute_script_tags(entry_point) %}
    {% for file in encore_entry_js_files(entry_point) %}
        <script src="{{ absolute_url(asset(file)) }}" ></script>
    {% endfor %}
{% endmacro %}```
poolerMF commented 5 years ago

+1

victorGI commented 4 years ago

+1

Surf-N-Code commented 4 years ago

+1

crabnky commented 4 years ago

+1 (first in 2020) :)

DerDu commented 2 years ago

What about configuration of public path ?

Assuming that your styles/scripts reside in /public/build/ In your webpack.config.js set the following:

Encore
    // directory where compiled assets will be stored
    .setOutputPath('public/build/')
    // public path used by the web server to access the output path
    .setPublicPath('https://your-domain.as-absolute-path.to/build')
    // only needed for CDN's or sub-directory deploy
    .setManifestKeyPrefix('build/')
    .cleanupOutputBeforeBuild()
...

Tadaaa.. Your tags are now rendered as https://your-domain.as-absolute-path.to/build/your-asset.css instead of /build/your-asset.css

TheRatG commented 2 years ago

Hi, I found RenderAssetTagEvent, so you can make subscriber.

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\UrlHelper;
use Symfony\WebpackEncoreBundle\Event\RenderAssetTagEvent;

class AbsoluteUrlAssetTagSubscriber implements EventSubscriberInterface
{
    private UrlHelper $urlHelper;

    public function __construct(UrlHelper $urlHelper)
    {
        $this->urlHelper = $urlHelper;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            RenderAssetTagEvent::class => 'onRenderAssetTag',
        ];
    }

    public function onRenderAssetTag(RenderAssetTagEvent $event): void
    {
        $path = $event->getUrl();
        $src = $this->urlHelper->getAbsoluteUrl($path);
        if ($event->isLinkTag()) {
            $event->setAttribute('href', $src);
        } elseif ($event->isScriptTag()) {
            $event->setAttribute('src', $src);
        }
    }
}
i-Tor commented 1 year ago

Sorry, this doesn't belong here. I had two windows open about the same issue and commented in the wrong one.

--

maknotmark commented 1 year ago

What about configuration of public path ?

Assuming that your styles/scripts reside in /public/build/ In your webpack.config.js set the following:

Encore
    // directory where compiled assets will be stored
    .setOutputPath('public/build/')
    // public path used by the web server to access the output path
    .setPublicPath('https://your-domain.as-absolute-path.to/build')
    // only needed for CDN's or sub-directory deploy
    .setManifestKeyPrefix('build/')
    .cleanupOutputBeforeBuild()
...

Tadaaa.. Your tags are now rendered as https://your-domain.as-absolute-path.to/build/your-asset.css instead of /build/your-asset.css

This has helped me reference the correct path.

Instead of having:

'https://your-domain.as-absolute-path.to/build/index.php/your-asset.css'

it is now outputted as:

'https://your-domain.as-absolute-path.to/build/our-asset.css'

bdujon commented 10 months ago

as a workaround you can use the base html element : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base It will work with every asset / url rendered by twig. Works nicely so far with puppeteer inside of a docker

zpottie commented 4 months ago

+1 - Needed in PDF generation as well.