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

Allow resource handles to be passed into svg() twig function #2838

Closed
wants to merge 1 commit into from

Conversation

jcherniak
Copy link
Contributor

This allows you to take SVG-based assets and include them inline in TWIG.

{{ svg(asset.stream) }}

Combined with my plugin, you can then include it sanitized and inline as a data uri like:

<img src="{{ svg(asset.stream) | dataUri(false, "image/svg+xml") }}" alt="{{ asset.title }}" />

@brandonkelly
Copy link
Member

Couldn’t you just give the asset a __toString() method? PHP will automatically convert it to a string when it’s passed to that function, if so.

@jcherniak
Copy link
Contributor Author

This is happening in TWIG and asset is a craft\elements\Asset object. Asset::__toString returns the title, not the contents of the file.

@jcherniak
Copy link
Contributor Author

jcherniak commented May 2, 2018

I could see adding Asset::getFileContents which contains:

function getFileContents() { return stream_get_contents($this->getStream); }

as another way to fix this.

@brandonkelly
Copy link
Member

Ahh, so your plugin is adding the getStream() method to assets. Yeah, in that case, a separate getContents() method would do the trick.

@jcherniak
Copy link
Contributor Author

My plugin isn't doing anything to the asset, that's the built-in Asset class. My plugin is simply taking the resulting output from the SVG() function and forming it into a data-uri.

To be clear, the bug here is that this doesn't work:

  1. Create a new asset source.
  2. Upload a SVG into it.
  3. You want inline SVG in your twig template based on the file, so...
    3a. Create an asset field called "asset"
    3b. In TWIG do something like the following:

{{ svg(entry.asset.stream) }}

I'd expect that to output inline SVG, but instead without this patch, I get a crash:
image

Passing the asset itself:

{{ svg(entry.asset) }}

produces empty output.

The only way I could get this to work w/o a patch is:
{{ svg(entry.asset.volume.path ~ "/" ~ entry.asset.fileName) }}

That works fine in this case, but if you have a non-local folder, this will not work. Hence my suggestion to allow svg() to accept streams (or add \craft\elements\Asset::getFileContents()). That way you could read SVG files from remote volumes.

@jcherniak
Copy link
Contributor Author

To be clear, when I mention getStream, I'm referring to this: https://github.com/craftcms/cms/blob/develop/src/elements/Asset.php#L900

@brandonkelly
Copy link
Member

Doh, I didn’t even realize we added that function! 🙃

I just added a check for actual Asset objects in the svg() method, so you can just do this: {{ svg(asset) }}.

Thanks for bearing with me.

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

Successfully merging this pull request may close these issues.

2 participants