{% else %}
diff --git a/bundle/Templating/Twig/Extension/RemoteMediaExtension.php b/bundle/Templating/Twig/Extension/RemoteMediaExtension.php
index 600a0c1d..34839846 100644
--- a/bundle/Templating/Twig/Extension/RemoteMediaExtension.php
+++ b/bundle/Templating/Twig/Extension/RemoteMediaExtension.php
@@ -57,6 +57,10 @@ public function getFunctions(): array
'ngrm_remote_resource_html_tag',
[RemoteMediaRuntime::class, 'getRemoteResourceHtmlTag'],
),
+ new TwigFunction(
+ 'ngrm_remote_resource_location_html_tag',
+ [RemoteMediaRuntime::class, 'getRemoteResourceLocationHtmlTag'],
+ ),
new TwigFunction(
'ngrm_remote_resource_variation_html_tag',
[RemoteMediaRuntime::class, 'getRemoteResourceVariationHtmlTag'],
diff --git a/bundle/Templating/Twig/Runtime/RemoteMediaRuntime.php b/bundle/Templating/Twig/Runtime/RemoteMediaRuntime.php
index 962ef9f3..fd34b2b0 100644
--- a/bundle/Templating/Twig/Runtime/RemoteMediaRuntime.php
+++ b/bundle/Templating/Twig/Runtime/RemoteMediaRuntime.php
@@ -107,6 +107,11 @@ public function getRemoteResourceHtmlTag(RemoteResource $resource, array $htmlAt
return $this->provider->generateHtmlTag($resource, $htmlAttributes, $forceVideo, $useThumbnail);
}
+ public function getRemoteResourceLocationHtmlTag(RemoteResourceLocation $location, array $htmlAttributes = [], bool $forceVideo = false, bool $useThumbnail = false): string
+ {
+ return $this->provider->generateLocationHtmlTag($location, $htmlAttributes, $forceVideo, $useThumbnail);
+ }
+
public function getRemoteResourceVariationHtmlTag(
RemoteResourceLocation $location,
string $variationGroup,
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index be963ef8..6224a610 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -6,6 +6,8 @@
* `cloudinary.use_asset_folder_as_public_id_prefix` option which prefixes the public ID with the asset folder in `dynamic` folder mode, so the same file can be uploaded to different folders
* upload error for an existing resource now names the folder when the conflict is limited to that folder
+* alt text and caption overrides on `RemoteResourceLocation` (`alt_text_override` and `caption_override` columns), editable in the interface and configurable for named locations (`alt_text` and `caption`), which take precedence over the values stored on the cloud
+* `ngrm_remote_resource_location_html_tag` TWIG function and `ProviderInterface::generateLocationHtmlTag()` which render the resource of a location with its overrides
### Changed
diff --git a/docs/FORM.md b/docs/FORM.md
index a15fd718..385c3c9c 100644
--- a/docs/FORM.md
+++ b/docs/FORM.md
@@ -49,6 +49,23 @@ The above example will make sure that, when you select a new resource in the for
The reason why we're using `OneToOne` relation here is because the idea is that every usage of a remote resource has it's own location. Things such as cropping settings or watermark text are stored in a location, and you want to have different cropping settings for the same eg. image used on different places.
+## Alt text and caption overrides
+
+Alt text and caption entered in the interface are stored on the resource in the cloud, so changing them updates every location which uses that resource. Each location can additionally have its own alt text and caption override (`altTextOverride` and `captionOverride` fields of the form), stored only on that location and never sent to the cloud. An empty override means that the value from the cloud is used.
+
+`RemoteResourceLocation::getAltText()` and `RemoteResourceLocation::getCaption()` return the override when it's set and the value from the cloud otherwise, so use them (eg. `location.caption` in TWIG) instead of the ones on the resource when rendering a location:
+
+```twig
+{{ ngrm_remote_resource_variation_html_tag(location, 'default', 'wide') }}
+{{ ngrm_remote_resource_location_html_tag(location) }}
+
+{% if location.caption is not empty %}
+ {{ location.caption }}
+{% endif %}
+```
+
+Both TWIG functions render the overrides as `alt` and `title` attributes of images and video thumbnails, unless those attributes are explicitly provided. `ngrm_remote_resource_html_tag` receives only the resource, so it always uses the values from the cloud.
+
## Add field to your form
Now when we have the entity configured properly, it's time to add the form field:
diff --git a/docs/NAMED_OBJECTS.md b/docs/NAMED_OBJECTS.md
index 2e8e3c6d..a0b4bbb0 100644
--- a/docs/NAMED_OBJECTS.md
+++ b/docs/NAMED_OBJECTS.md
@@ -19,11 +19,13 @@ netgen_remote_media:
### Remote resource location
-If you also need a location for that resource, it's possible by using configuration for locations. Configuration consists of key, value pairs, where key is the desired name (eg. `my_resource_location`) and value is another array which accepts three keys:
+If you also need a location for that resource, it's possible by using configuration for locations. Configuration consists of key, value pairs, where key is the desired name (eg. `my_resource_location`) and value is another array which accepts the following keys:
- `resource_remote_id` - remote ID of the resource on the cloud
- `source` (optional) - text that will be used for the location source (eg. `named_my_resource_location`)
- `watermark_text` (optional) - watermark text which can be used if a watermaked variation gets built from that location
+- `alt_text` (optional) - alt text override for the location, used instead of the alt text stored on the cloud
+- `caption` (optional) - caption override for the location, used instead of the caption stored on the cloud
Example:
@@ -35,6 +37,7 @@ netgen_remote_media:
resource_remote_id: 'upload|image|folder/my_resource'
source: 'named_my_resource_location'
watermark_text: 'Netgen.io'
+ alt_text: 'Netgen logo'
```
## Usage
diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md
index 0512ffbd..8d882f9e 100644
--- a/docs/UPGRADE.md
+++ b/docs/UPGRADE.md
@@ -36,6 +36,9 @@ Also, there were a lot of changes during the decoupling from eZ to make things c
* `public static function createFromCloudinaryResponse(array $response): self`
* The bundle was using eZ's `ezpublish.cache_pool` cache pool for caching while it was depending on eZ. Now it requires cache pool to be provided in order to work. See [Install instructions](INSTALL.md) for more info.
* Parameter for cache TTL `netgen_remote_media.cloudinary.cache_ttl` has been removed in favour of semantic configuration for cache. See [Install instructions](INSTALL.md) for more info.
+* `RemoteResourceLocation` can hold alt text and caption overrides which take precedence over the values stored on the cloud (see [Form documentation](FORM.md#alt-text-and-caption-overrides)). If you already created the database tables for 3.0, add the new columns with `php bin/console doctrine:schema:update` (check the output of `--dump-sql` first), or manually:
+ * MySQL: `ALTER TABLE ngrm_remote_resource_location ADD alt_text_override TEXT DEFAULT NULL, ADD caption_override TEXT DEFAULT NULL;`
+ * PostgreSQL: `ALTER TABLE ngrm_remote_resource_location ADD alt_text_override TEXT DEFAULT NULL, ADD caption_override TEXT DEFAULT NULL;`
### Code changes
diff --git a/frontend/src/components/Interactions.vue b/frontend/src/components/Interactions.vue
index 78f6c6c6..d932eac3 100644
--- a/frontend/src/components/Interactions.vue
+++ b/frontend/src/components/Interactions.vue
@@ -152,6 +152,8 @@ export default {
alternateText: item.altText,
caption: item.caption,
watermarkText: this.selectedImage.watermarkText,
+ altTextOverride: '',
+ captionOverride: '',
tags: item.tags,
size: item.size,
variations: {},
@@ -187,6 +189,8 @@ export default {
alternateText: item.altText,
caption: item.caption,
watermarkText: this.selectedImage.watermarkText,
+ altTextOverride: '',
+ captionOverride: '',
tags: item.tags,
size: item.size,
variations: {},
@@ -215,6 +219,8 @@ export default {
alternateText: '',
caption: '',
watermarkText: this.selectedImage.watermarkText,
+ altTextOverride: '',
+ captionOverride: '',
tags: [],
size: 0,
variations: {},
diff --git a/frontend/src/components/Preview.vue b/frontend/src/components/Preview.vue
index 25247317..5c870432 100644
--- a/frontend/src/components/Preview.vue
+++ b/frontend/src/components/Preview.vue
@@ -58,6 +58,36 @@
>
+
+
+ {{this.config.translations.preview_alternate_text_override}}
+
+
+
+
+
+
+
+
+ {{this.config.translations.preview_caption_override}}
+
+
+
+
+
+