Skip to content

Commit

Permalink
Allow importing asset alt text (#50)
Browse files Browse the repository at this point in the history
* Allow importing asset alt text

* Fix styling

* wip

* wip

* Make this `values` instead.

---------

Co-authored-by: duncanmcclean <[email protected]>
  • Loading branch information
duncanmcclean and duncanmcclean authored Nov 29, 2024
1 parent c2044ff commit f1d3149
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 7 deletions.
2 changes: 2 additions & 0 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ When you're configuring mappings for an Assets field, or a Bard field, a few add
* However, if you wish, the importer can download any missing assets for you into the configured asset container.
* **Folder**
* By default, downloaded assets will use same folder structure as the original URL. If you'd like to download them into a specific folder, you can select one here.
* **Alt Text**
* Determine which field in the row contains the alt text for the asset. This option will only be shown when the Asset blueprint has an `alt` field.

When importing a Bard field, assets will only be imported when the "Container" config option has been set in the blueprint.

Expand Down
1 change: 1 addition & 0 deletions lang/en/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'strategy_instructions' => 'Choose what should happen when importing.',
'unique_field_instructions' => 'Select a "unique field" to determine if an item already exists.',

'assets_alt_instructions' => 'Which field should be used for the alt text?',
'assets_base_url_instructions' => 'The base URL to prepend to the path.',
'assets_download_when_missing_instructions' => 'If the asset can\'t be found in the asset container, should it be downloaded?',
'assets_folder_instructions' => 'By default, downloaded assets will use same folder structure as the original URL. You can specify a different folder here.',
Expand Down
2 changes: 1 addition & 1 deletion src/Fieldtypes/ImportMappingsFieldtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private function fields(): Collection
$fields = [];

if ($transformer = Importer::getTransformer($field->type())) {
$fields = (new $transformer(field: $field))->fieldItems();
$fields = (new $transformer(import: $import, field: $field))->fieldItems();
}

$blueprint = Blueprint::makeFromFields([
Expand Down
2 changes: 1 addition & 1 deletion src/Jobs/ImportItemJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function handle(): void
}

if ($transformer = Importer::getTransformer($field->type())) {
$value = (new $transformer($this->import, $blueprint, $field, $mapping))->transform($value);
$value = (new $transformer($this->import, $blueprint, $field, $mapping, $this->item))->transform($value);
}

return [$fieldHandle => $value];
Expand Down
3 changes: 2 additions & 1 deletion src/Transformers/AbstractTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ public function __construct(
protected ?Import $import = null,
protected ?Blueprint $blueprint = null,
protected ?Field $field = null,
protected ?array $config = null
protected ?array $config = null,
protected ?array $values = null,
) {}

abstract public function transform(string $value);
Expand Down
28 changes: 27 additions & 1 deletion src/Transformers/AssetsTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use Statamic\Facades\Asset;
use Statamic\Facades\AssetContainer;
use Statamic\Facades\Path;
use Statamic\Importer\Sources\Csv;
use Statamic\Importer\Sources\Xml;
use Statamic\Support\Arr;
use Statamic\Support\Str;

class AssetsTransformer extends AbstractTransformer
Expand Down Expand Up @@ -53,6 +56,10 @@ public function transform(string $value): null|string|array
$asset->save();
}

if ($alt = $this->config('alt')) {
$asset?->set('alt', Arr::get($this->values, $alt))->save();
}

return $asset?->path();
})->filter();

Expand Down Expand Up @@ -86,7 +93,7 @@ private function assetPath(AssetContainerContract $assetContainer, string $path)

public function fieldItems(): array
{
return [
$fieldItems = [
'related_field' => [
'type' => 'select',
'display' => __('Related Field'),
Expand Down Expand Up @@ -119,5 +126,24 @@ public function fieldItems(): array
'max_items' => 1,
],
];

if (AssetContainer::find($this->field->get('container'))->blueprint()->hasField('alt')) {
$row = match ($this->import?->get('type')) {
'csv' => (new Csv($this->import))->getItems($this->import->get('path'))->first(),
'xml' => (new Xml($this->import))->getItems($this->import->get('path'))->first(),
};

$fieldItems['alt'] = [
'type' => 'select',
'display' => __('Alt Text'),
'instructions' => __('importer::messages.assets_alt_instructions'),
'options' => collect($row)->map(fn ($value, $key) => [
'key' => $key,
'value' => "<{$key}>: ".Str::truncate($value, 200),
])->values()->all(),
];
}

return $fieldItems;
}
}
70 changes: 69 additions & 1 deletion tests/Transformers/AssetsTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class AssetsTransformerTest extends TestCase
{
use PreventsSavingStacheItemsToDisk;

public $assetContainer;
public $collection;
public $blueprint;
public $field;
Expand All @@ -26,7 +27,7 @@ protected function setUp(): void
{
parent::setUp();

AssetContainer::make('assets')->disk('public')->save();
$this->assetContainer = tap(AssetContainer::make('assets')->disk('public'))->save();

$this->collection = tap(Collection::make('pages'))->save();

Expand Down Expand Up @@ -160,4 +161,71 @@ public function it_doesnt_download_new_asset_when_download_when_missing_option_i

Storage::disk('public')->assertMissing('2024/10/image.png');
}

#[Test]
public function it_sets_alt_text_on_existing_asset()
{
Http::preventStrayRequests();

Storage::disk('public')->put('2024/10/image.png', 'original');

$transformer = new AssetsTransformer(
import: $this->import,
blueprint: $this->blueprint,
field: $this->field,
config: [
'related_field' => 'url',
'base_url' => 'https://example.com/wp-content/uploads',
'alt' => 'Image Alt Text',
],
values: [
'Image Alt Text' => 'A photo taken by someone.',
],
);

$asset = $this->assetContainer->asset('2024/10/image.png');
$this->assertNull($asset->get('alt'));

$output = $transformer->transform('https://example.com/wp-content/uploads/2024/10/image.png');
$this->assertEquals('2024/10/image.png', $output);

$asset = $this->assetContainer->asset('2024/10/image.png');
$this->assertEquals('A photo taken by someone.', $asset->get('alt'));
}

#[Test]
public function it_sets_alt_text_on_downloaded_asset()
{
Http::fake([
'https://example.com/wp-content/uploads/2024/10/image.png' => Http::response(UploadedFile::fake()->image('image.png')->size(100)->get()),
]);

Storage::disk('public')->assertMissing('2024/10/image.png');

$transformer = new AssetsTransformer(
import: $this->import,
blueprint: $this->blueprint,
field: $this->field,
config: [
'related_field' => 'url',
'base_url' => 'https://example.com/wp-content/uploads',
'download_when_missing' => true,
'alt' => 'Image Alt Text',
],
values: [
'Image Alt Text' => 'A photo taken by someone.',
],
);

$this->assertNull($this->assetContainer->asset('2024/10/image.png'));

$output = $transformer->transform('https://example.com/wp-content/uploads/2024/10/image.png');

$this->assertEquals('2024/10/image.png', $output);

Storage::disk('public')->assertExists('2024/10/image.png');

$asset = $this->assetContainer->asset('2024/10/image.png');
$this->assertEquals('A photo taken by someone.', $asset->get('alt'));
}
}
4 changes: 2 additions & 2 deletions tests/WordPress/GutenbergTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public function it_transforms_image_blocks()
field: $this->blueprint->field('content'),
value: <<<'HTML'
<!-- wp:image {"id":41,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://example.com/wp-content/uploads/2024/10/image.png" alt="" class="wp-image-41"/></figure>
<figure class="wp-block-image size-large"><img src="https://example.com/wp-content/uploads/2024/10/image.png" alt="A cool photo of a thing." class="wp-image-41"/></figure>
<!-- /wp:image -->
HTML
);
Expand All @@ -212,7 +212,7 @@ public function it_transforms_image_blocks()
'type' => 'image',
'attrs' => [
'src' => 'assets::2024/10/image.png',
'alt' => null,
'alt' => 'A cool photo of a thing.',
],
],
],
Expand Down

0 comments on commit f1d3149

Please sign in to comment.