Grav でコンテンツを作成する際、画像や動画、その他の様々な異なる種類のファイルを表示する必要があることがよくあります。これらのファイルは、Gravが自動的に検出・処理し、ページで利用できます。特に、サムネイルやメタデータへのアクセス、メディアの動的な変更(画像のリサイズや動画の表示サイズの設定など)を、ページの組み込み機能を使うことができるため、非常に便利です。
Grav は、必要に応じて動的に生成されたファイルのコピーを自動的にキャッシュ内に作成するスマートキャッシングシステムを使用しています。こうすることで、それ以降のすべてのリクエストは、ファイルをもう一度生成する代わりに、キャッシュされたバージョンを使用することができます。
Grav が標準でサポートしているファイル形式は次のとおりです。他のファイルやストリーミングの埋め込みのサポートは、プラグインによって追加される場合があります。
分類 | 種類 |
---|---|
画像 | jpg, jpeg, png |
音声 | mp3, wav, wma, ogg, m4a, aiff, aif |
画像(動画) | gif |
ベクター画像 | svg |
動画 | mp4, mov, m4v, swf, flv, webm, ogv |
その他のデータ形式 | txt, doc, docx, html, htm, pdf, zip, gz, 7z, tar, css, js, json, xml, xls, xlt, xlm, xlsm, xld, xla, xlc, xlw, xll, ppt, pps, rtf, bmp, tiff, mpeg, mpg, mpe, avi, wmv |
サポートされている mime-type の完全なリストは、system/config/media.yaml
ファイルに記載されています。現在サポートされていない mime-type がある場合は、user/config/media.yaml
を作成し、そこに追加することができます。ただし、元のシステムファイルと同じ状態であることを確認してください。最も簡単な方法は、元のファイル全体をコピーして、編集することです。
ファイルを利用するページのフォルダに置くだけ利用できます。
![my image](image.jpg)
もし、すべての画像を一つのフォルダに入れたいのであれば、user/pages/images
フォルダに入れることができます。その場合、Twig で、以下の方法でアクセスできます。
{% set my_image = page.find('/images').media['my-image.jpg'] %}
マークダウンから、画像の加工を実行することができます。
![my image](/images/my-image.jpg?cropResize=300,300)
CSS参照や、theme://
を使用して、マークダウンから簡単にアクセスできるため、テーマに配置することもできます。
![my image](theme://images/theme-image.jpg)
別の方法として、user/images
を利用することで、image://
を使ってアクセスすることができます。
![my image](image://my-image.jpg)
user://
を利用すれば、user/
内の任意のフォルダを含む任意のファイルを使用することができます。
![my image](user://themes/mytheme/images/my-image.jpg)
TwigMedia オブジェクトを使用して、これらと同等のことを行うこともできます。
{{ media['user://themes/mytheme/images/my-image.jpg'].html()|raw }}
Grav には /images
フォルダが存在しますが、このフォルダには、Grav が自動生成した画像やキャッシュした画像が格納されているので、自分の画像を入れないでください。
すべてのメディアファイルを独自のフォルダに入れ、一度にアクセスできるようにしたい場合もあります。たとえば、すべてのMP3ファイルをuser/pages/mp3s というフォルダ(表示されません)に保存し、特定のページに関連する MP3 ファイルの名前を thistrack というヘッダーフィールドに記述することができます。そして、特定のページのファイルにアクセスし、HTML5 の audio を使って再生したい場合は、次のようなコードが必要になります。
<audio controls>
<source src="{{ page.find('/mp3s').media[page.header.thistrack~'.mp3']|e }}">
</audio>
Grav provides a few different display modes for every kind of media object.
Mode | Explanation |
---|---|
source | Visual representation of the media itself, i.e. the actual image, video or file |
text | Textual representation of the media |
thumbnail | The thumbnail image for this media object |
Data / Information type media do not support source
mode, they will default to text
mode if another mode is not explicitly chosen.
There are three locations Grav will look for your thumbnail.
[media-name].[media-extension].thumb.[thumb-extension]
where media-name
and media-extension
are respectively the name and extension of the original media file and thumb-extension
is any extension that is supported by the image
media type. Examples are my_video.mp4.thumb.jpg
and my-image.jpg.thumb.png
user/images/media/thumb-[media-extension].png
where media-extension
is the extension of the original media file. Examples are thumb-mp4.png
and thumb-jpg.jpg
system/images/media/thumb-[media-extension].png
where media-extension
is the extension of the original media file. The thumbnails in the system folders are pre-provided by Grav.You can also manually select the desired thumbnail with the actions explained below.
The display modes above can also be used in combination with links and lightboxes, which are explained in more detail later. Important to note however is:
Grav does not provide lightbox-functionality out of the box, you need a plugin for this. You can use the FeatherLight Grav plugin to achieve this.
When you use Grav's media functionality to render a lightbox, all Grav does is output an anchor tag that has some attributes for the lightbox plugin to read. If you are interested in using a lightbox library that is not in our plugin repository or you want to create your own plugin, you can use the table below as a reference.
Attribute | Explanation |
---|---|
rel | A simple indicator that this is not a regular link, but a lightbox link. The value will always be lightbox . |
href | A URL to the media object itself. |
data-width | The width the user requested this lightbox to be. |
data-height | The height the user requested this lightbox to be. |
data-srcset | In case of image media, this contains the srcset string. (more info) |
Grav employs a builder-pattern when handling media, so you can perform multiple actions on a particular medium. Some actions are available for every kind of medium while others are specific to the medium.
These actions are available for all media types.
This method is only intended to be used in Twig templates, hence the lack of Markdown syntax.
This returns raw url path to the media.
{{ page.media['sample-image.jpg'].url|e }}
In Markdown this method is implicitly called when using the ![]
syntax.
The html
action will output a valid HTML tag for the media based on the current display mode.
![Some ALT text](sample-image.jpg?classes=myclass "My title")
{{ page.media['sample-image.jpg'].html('My title', 'Some ALT text', 'myclass')|raw }}
Use this action to switch between the various display modes that Grav provides. Once you switch display mode, all previous actions will be reset. The exceptions to this rule are the lightbox
and link
actions and any actions that have been used before those two.
For example, the thumbnail that results from calling page.media['sample-image.jpg'].sepia().display('thumbnail').html()
will not have the sepia()
action applied, but page.media['sample-image.jpg'].display('thumbnail').sepia().html()
will.
Once you switch to thumbnail mode, you will be manipulating an image. This means that even if your current media is a video, you can use all the image-type actions on the thumbnail.
Turn your media object into a link. All actions that you call before link()
will be applied to the target of the link, while any actions called after will apply to what's displayed on your page.
After calling link()
, Grav will automatically switch the display mode to thumbnail.
The following example will display a textual link (display('text')
) to a sepia version of the sample-image.jpg
file:
![Image link](sample-image.jpg?sepia&link&display=text)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].sepia().link().display('text').html('Image link')|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{{ page.media['sample-image.jpg'].sepia().link().display('text').html('Image link')|e }}
[/ui-tab]
[/ui-tabs]
Grav can be set to cache all image files, this may increase the speed that files are served. However, images will go through the Grav image manipulation system which may lead to a considerably larger file size for images that have already been optimized prior to Grav. Image manipulation can be bypassed.
Enable cache_all
in system/config/system.yaml
images:
default_image_quality: 85
cache_all: false
{% endverbatim %}
Disable image manipulation with the cache
option.
![](sample-image.jpg?cache)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cache.html()|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{{ page.media['sample-image.jpg'].cache.html()|e }}
[/ui-tab]
[/ui-tabs]
The lightbox action is essentially the same as the link action but with a few extras. Like explained above (Links and Lightboxes), the lightbox action will not do anything more than create a link with some extra attributes. It differs from the link action in that it adds a rel="lightbox"
attribute and accepts a width
and height
attribute.
If possible (currently only in the case of images), Grav will resize your media to the requested width and height. Otherwise it will simply add a data-width
and data-height
attribute to the link.
![Sample Image](sample-image.jpg?lightbox=600,400&resize=200,200)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].lightbox(600,400).resize(200,200).html('Sample Image')|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{{ page.media['sample-image.jpg'].lightbox(600,400).resize(200,200).html('Sample Image')|e }}
[/ui-tab]
[/ui-tabs]
Manually choose the thumbnail Grav should use. You can choose between page
and default
for any type of media as well as media
for image media if you want to use the media object itself as your thumbnail.
![Sample Image](sample-image.jpg?thumbnail=default&display=thumbnail)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].thumbnail('default').display('thumbnail').html('Sample Image')|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{{ page.media['sample-image.jpg'].thumbnail('default').display('thumbnail').html('Sample Image')|e }}
[/ui-tab]
[/ui-tabs]
This adds an additional HTML attribute to the output.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?attribute=myattribute,myvalue)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].attribute('myattribute', 'myvalue').html('Sample Image')|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{{ page.media['sample-image.jpg'].attribute('myattribute', 'myvalue').html('Sample Image')|e }}
[/ui-tab]
[/ui-tabs]
Resizing does exactly what you would expect it to do. resize
lets you create a new image based on the width
and the height
. The aspect ratio is maintained and the new image will contain blank areas in the color of the optional background color provided as a hex value
, e.g. 0xffffff
. The background parameter is optional, and if not provided will default to transparent if the image is a PNG, or white if it is a JPEG.
![Sample Image](sample-image.jpg?resize=400,200)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].resize(400, 200).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Resizes the image to the width
and height
as provided. forceResize
will not respect original aspect-ratio and will stretch the image as needed to fit the new image size.
![Sample Image](sample-image.jpg?forceResize=200,300)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].forceResize(200, 300).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
cropResize
resizes an image to a smaller or larger size based on the width
and the height
. The aspect ratio is maintained and the new image will be resized to fit in the bounding-box as described by the width
and height
provided. In other words, any background area you would see in a regular resize
is cropped.
For example, if you have an image that is 640
x 480
and you perform a cropResize(100, 100)
action upon it, you will end up with an image that is 100
x 75
.
![Sample Image](sample-image.jpg?cropResize=300,300)
{{ page.media['sample-image.jpg'].cropResize(300, 300).html()|raw }}
crop
will not resize the image at all, it will merely crop the original image so that only the portion of the bounding box as described by the width
and the height
originating from the x
and y
location is used to create the new image.
For example, an image that is 640
x 480
with crop(0, 0, 400, 100)
will produce an image with a width of 400
and a height of 100
originating from the top-left corner as described by 0, 0
.
![Sample Image](sample-image.jpg?crop=100,100,300,200)
{{ page.media['sample-image.jpg'].crop(100,100,300,200).html()|raw }}
Similar to regular cropResize
, cropZoom
also takes a width
and a height
but will resize and crop the image to ensure the resulting image is the exact size you requested. The aspect ratio is maintained but parts of the image may be cropped, however the resulting image is centered.
The primary difference between cropResize and cropZoom is that in cropResize, the image is resized maintaining aspect ratio so that the entire image is shown, and any extra space is considered background.
With cropZoom, the image is resized so that there is no background visible, and the extra image area of the image outside of the new image size is cropped.
For example if you have an image that is 640
x 480
and you perform a cropZoom(400, 100)
action, the resulting image will be resized to 400
x 300
and then the height is cropped resulting in a 400
x 100
image.
![Sample Image](sample-image.jpg?cropZoom=600,200)
{{ page.media['sample-image.jpg'].cropZoom(600,200).html()|raw }}
Folks familiar with using zoomCrop
for this purpose will find that it also works in Grav.
Dynamically allows the setting of a compression percentage value
for the image between 0
and 100
. A lower number means less quality, where 100
means maximum quality.
![Sample Image](sample-image.jpg?cropZoom=300,200&quality=25)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).quality(25).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Applies a negative filter to the image where colors are inverted.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?cropZoom=300,200&negate)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).negate.html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Applies a brightness filter to the image with a value
from -255
to +255
. Larger negative numbers will make the image darker, while larger positive numbers will make the image brighter.
![Sample Image](sample-image.jpg?cropZoom=300,200&brightness=-100)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).brightness(-100).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
This applies a contrast filter to the image with a value
from -100
to +100
. Larger negative numbers will increase the contrast, while larger positive numbers will reduce the contrast.
![Sample Image](sample-image.jpg?cropZoom=300,200&contrast=-50)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).contrast(-50).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
This processes the image with a grayscale filter.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?cropZoom=300,200&grayscale)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).grayscale.html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
This processes the image with an embossing filter.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?cropZoom=300,200&emboss)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).emboss.html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
This applies a smoothing filter to the image based on smooth value
setting from -10
to 10
.
![Sample Image](sample-image.jpg?cropZoom=300,200&smooth=5)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).smooth(5).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
This applies a sharpening filter on the image.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?cropZoom=300,200&sharp)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).sharp.html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
This applies an edge finding filter on the image.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?cropZoom=300,200&edge)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).edge.html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
You can colorize the image based on adjusting the red
, green
, and blue
values for the image from -255
to +255
for each color.
![Sample Image](sample-image.jpg?cropZoom=300,200&colorize=100,-100,40)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).colorize(100,-100,40).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
This applies a sepia filter on the image to produce a vintage look.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?cropZoom=300,200&sepia)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).sepia.html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
blurs the image by an Factor, that defines how often the blur filter is applied to the image. Default is 1 time.
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?gaussianBlur=3)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].gaussianBlur(3).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
rotates the image by angle
degrees counterclockwise, negative values rotate clockwise.
![Sample Image](sample-image.jpg?cropZoom=300,200&rotate=-90)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).rotate(-90).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
flips the image in the given directions. Both params can be 0|1
. Both 0
is equivalent to no flipping in either direction.
![Sample Image](sample-image.jpg?cropZoom=300,200&flip=0,1)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].cropZoom(300,200).flip(0,1).html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Fixes the orientation of the image when rotation is made via EXIF data (applies to jpeg images taken with phones and cameras).
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?fixOrientation)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].fixOrientation().html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
The loading attributing on images gives authors control over when the browser should start loading the resource. The value for the loading attribute can be one of auto
(default), lazy
, eager
.
Value can be set in system.images.defaults.loading
as default value, or per md image with ?loading=lazy
When value auto
is chosen, no loading
attribute is added and browser will determine which strategy to use.
![Sample Image](sample-image.jpg?loading=lazy)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{# Using default value as defined in 'config.system.images.defaults.loading' #}
{{ page.media['sample-image.jpg'].loading.html('Sample Image')|raw }}
{# Using explicit value #}
{{ page.media['sample-image.jpg'].loading('lazy').html('Sample Image')|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
<img loading="lazy" title="Sample Image" src="/images/e/f/1/0/5/ef10554cd3a99f2e65136e79dce170d4f8a7a1b9-sample-image.jpg" />
[/ui-tab]
[/ui-tabs]
Because PHP cannot handle dynamically resizing these types of media, the resize action will only make sure that a width
and height
or data-width
and data-height
attribute are set on your <img>
/<video>
or <a>
tag respectively. This means your image or video will be displayed in the requested size, but the actual image or video file will not be converted in any way.
![Sample Trailer](sample-trailer.mov?resize=400,200)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-trailer.mov'].resize(400, 200).html('Sample Trailer')|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{{ page.media['sample-trailer.mov'].resize(400, 200).html('Sample Trailer')|e }}
[/ui-tab]
[/ui-tabs]
Some examples of this:
[ui-tabs] [ui-tab title="Vector Image"]![Sample Vector](sample-vector.svg?resize=300,300)
[/ui-tab]
[ui-tab title="Animated Image"]
![Animated Gif](sample-animated.gif?resize=300,300)
[/ui-tab]
[ui-tab title="Video"]
![Sample Trailer](sample-trailer.mov?resize=400,200)
[/ui-tab]
[/ui-tabs]
Audio media will display an HTML5 audio link:
[ui-tabs] [ui-tab title="Markdown"]![Hal 9000: I'm Sorry Dave](hal9000.mp3)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['hal9000.mp3'].html()|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Allows explicitly setting or removing the HTML5 default controls. Passing 0
hides browser's controls for playback, volume, etc..
![Hal 9000: I'm Sorry Dave](hal9000.mp3?controls=0)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['hal9000.mp3'].controls(0)|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{{ page.media['hal9000.mp3'].controls(0)|e }}
[/ui-tab]
[/ui-tabs]
Allows setting of preload
property, which defaults to auto
. Permitted params are auto
, metadata
, and none
.
If not set, its default value is browser-defined (i.e. each browser may have its own default value). The spec advises it to be set to
metadata
.
The preload
attribute is ignored if autoplay
is present.
![Hal 9000: I'm Sorry Dave](hal9000.mp3?preload=metadata)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['hal9000.mp3'].preload('metadata')|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Allows setting whether audio will autoplay
upon page load. Defaults to false
by omission if not set.
If autoplay
and preload
are both present on a given audio
element, preload
will be ignored.
![Hal 9000: I'm Sorry Dave](hal9000.mp3?autoplay=1)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['hal9000.mp3'].autoplay(1)|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Allows setting of controlsList
property, which takes one or more of three possible values: nodownload
, nofullscreen
, and noremoteplayback
.
If setting more than one parameter in markdown, separate each with a dash (-
). These will be replaced by spaces in the output HTML.
![Hal 9000: I'm Sorry Dave](hal9000.mp3?controlsList=nodownload-nofullscreen-noremoteplayback)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['hal9000.mp3'].controlsList('nodownload nofullscreen noremoteplayback')|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Allows setting whether audio is muted
on load. Defaults to false
by omission if not set.
![Hal 9000: I'm Sorry Dave](hal9000.mp3?muted=1)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['hal9000.mp3'].muted(1)|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Allows setting whether audio will loop
upon playing through completion. Defaults to false
by omission if not set.
![Hal 9000: I'm Sorry Dave](hal9000.mp3?loop=1)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['hal9000.mp3'].loop(1)|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
Grav does not provide any custom actions on files at this point in time and there are no plans to add any. Should you think of something, please contact us.
[ui-tabs] [ui-tab title="Markdown"][View Text File](acronyms.txt)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
<a href="{{ page.media['acronyms.txt'].url()|raw }}">View Text File</a>
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
As you can see: Grav provides some powerful image manipulation functionality that makes it really easy to work with images! The real power comes when you combine multiple effects and produce some very sophisticated dynamic image manipulations. For example, this is totally valid:
[ui-tabs] [ui-tab title="Markdown"]![Sample Image](sample-image.jpg?negate&lightbox&cropZoom=200,200)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['sample-image.jpg'].negate.lightbox.cropZoom(200,200)|raw }}
{% endverbatim %}
[/ui-tab]
[/ui-tabs]
When you access the same image multiple times in a single page, actions you have provided to the image are not reset by default. So if you resize an image, and output the HTML, then later in the same page, simply output the image URL, you will also get the URL to the resized image. You were probably expecting the URL to the original image.
To combat this, you can reset the actions on the images by passing false
to the url()
method:
{% for item in page.header.gallery %}
{% set image = page.media[item.src].cropZoom(800, 600).quality(70) %}
<a href="{{ image.url(false)|e }}">
<img src="{{ image.url|e }}" alt="{{ item.alt|e }}" title="{{ item.title|e }}" />
</a>
{% endfor %}
{% endverbatim %}
Grav has built-in support for responsive images for higher density displays (e.g. Retina screens). Grav accomplishes this by implementing srcset
from the Picture element HTML proposal. A good article to read if you want to understand this better is this blog post by Eric Portis.
Grav sets the sizes
argument mentioned in the posts above to full viewport width by default. Use the sizes
action showcased below to choose yourself.
To start using responsive images, all you need to do is add higher density images to your pages by adding a suffix to the file name. If you only provide higher density images, Grav will automatically generate lower quality versions for you. Naming works as follows: [image-name]@[density-ratio]x.[image-extension]
, so for example adding sample-image@3x.jpg
to your page will result in Grav creating a 2x
and a 1x
(regular size) version by default.
These files generated by Grav will be stored in the images/
cache folder, not your page folder.
Let's assume you have a file called retina@2x.jpg
, you would actually reference this in your links as retina.jpg
, and then Grav will not find this image, and start looking for retina image sizes. It will find retina@2x.jpg
and then realize it needs to make a @1x
variant and display the appropriate srcset
output:
![Retina Image](retina.jpg?sizes=80vw)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['retina.jpg'].sizes('80vw').html()|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{% set code_sample %}
{% endset %}
{{ code_sample|e }}
[/ui-tab]
[/ui-tabs]
Depending on your display and your browser's implementation and support for srcset
, you might never see a difference. We included the HTML markup in the third tab so you can see what's happening behind the screens.
Grav also has support for media queries inside the sizes
attribute, allowing you to use different widths depending on the device's screen size. In contrast to the first method, you don't have to create multiple images; they will get created automatically. The fallback image is the current image, so a browser without support for srcset
, will display the original image.
![Retina Image](retina.jpg?sizes=%28max-width%3A26em%29+100vw%2C+50vw)
[/ui-tab]
[ui-tab title="Twig"]
{% verbatim %}
{{ page.media['retina.jpg'].sizes('(max-width:26em) 100vw, 50vw').html('Retina Image')|raw }}
{% endverbatim %}
[/ui-tab]
[ui-tab title="HTML Code"]
{% set code_sample %}
{% endset %}
{{ code_sample|e }}
[/ui-tab]
[/ui-tabs]
Depending on your display and your browser's implementation and support for srcset
, you might never see a difference. We included the HTML markup in the fourth tab so you can see what's happening behind the screens.
If you want to customize the sizes of the automatically created files, you can use the derivatives()
method (as shown below). The first parameter is the width of the smallest of the generated images. The second is the maximum width of the generated images. The third, and only optional parameter, dictates the intervals with which to generate the photos (default is 200). For example, if you set the first parameter to be 320
and the third to be 100
, Grav will generate an image for 320, 420, 520, 620, and so on until it reaches its set maximum.
In our example, we set the maximum to 1600
. This will result in increments of 300 being met from 320
to 1520
as 1620
would be above the threshold.
For the moment it does not work inside markdown, only in your twig
files.
![Retina Image](retina.jpg?derivatives=320,1600,300&sizes=%28max-width%3A26em%29+100vw%2C+50vw)
{{ page.media['retina.jpg'].derivatives(320,1600,300).sizes('(max-width:26em) 100vw, 50vw').html()|raw }}
{% set code_sample %}
{% endset %}
{{ code_sample|e }}
Depending on your display and your browser's implementation and support for srcset
, you might never see a difference. We included the HTML markup in the fourth tab so you can see what's happening behind the screens.
Instead of letting Grav generate the sizes in even steps between given boundaries, you may manually define which sizes Grav should generate:
![Retina Image](retina.jpg?derivatives=[360,720,1200])
This will generate downsized versions of the retina.jpg
image in three widths: 360, 720 and 1200px.
Every medium that you reference in Grav, e.g. image1.jpg
, sample-trailer.mov
, or even archive.zip
has the ability to have variables set or even overridden via a metafile. These files take the format of <filename>.meta.yaml
. For example, for an image with the filename image1.jpg
you could create a metafile called image1.jpg.meta.yaml
.
You can add just about any setting or piece of metadata you would like using this method.
The contents of this file should be in YAML syntax, an example could be:
image:
filters:
default:
- [cropResize, 300, 300]
- sharp
alt_text: My Alt Text
If you are using this method to add file-specific styling or meta tags for a single file, you will want to put the YAML file in the same folder as the referenced file. This will ensure that the file is pulled along with the YAML data. It's a handy way to even set file-specific metadata as you are unable to do so from the page itself.
Let's say you wanted to just pull the alt_text
value listed for the image file sample-image.jpg
. You would then create a file called sample-image.jpg.meta.yaml
and place it in the folder with the referenced image file. Then, insert the data used in the example above and save that YAML file. In the markdown file for the page, you can display this data by using the following line:
{{ page.media['sample-image.jpg'].meta.alt_text|e }}
{% endverbatim %}
This will pull up the example phrase My Alt Text
instead of the image. This is just a basic example. You can use this method for a number of things, including creating a gallery with multiple unique data points you want to have referenced for each image. Your images, in essence, have a set of data unique to them that can be easily referenced and pulled as needed.
In-line video control options are another capability baked into Grav. These options, added in-line with the file name, give you the ability to determine an embedded video's autoplay
, controls
, and loop
settings.
Here is an example:
![video.mov](video.mov?loop=1&controls=0&autoplay=1&muted)
The options are as follows:
Attribute | Explanation |
---|---|
autoplay | Enables (1 ) or Disables (0 ) autoplay for the video on pageload. |
controls | Enables (1 ) or Disables (0 ) media controls for the embedded video. |
loop | Enables (1 ) or Disables (0 ) automatic looping for the video, replaying it as it ends. |
muted | Mute video and generally allow it to autoplay. |
オリジナル : https://learn.getgrav.org/17/content/media