Button for Link to Media

Hello all. Through an HTML <script> tag within an HTML block, how can I dynamically make a link to an item’s media page of a certain type?

Here is the code that (mostly) works:

<div class="preview-block clearfix">[items class_label=Interview]</div>
<script type="text/javascript">
  document.addEventListener('DOMContentLoaded', function() {
    const items = document.querySelectorAll('.resource.item');

    items.forEach(function(item) {
      const itemThumb = item.querySelector('.resource.item a').firstChild;
      itemThumb.classList.add('item-thumbnail');

      // Extract the item ID from the title link
      const idMatch = item.querySelector('h4 a').getAttribute('href').match(/\/item\/(\d+)/);
      if (idMatch) {
        const itemID = idMatch[1];

        // Create Button Learn
        const buttonLearn = document.createElement('a');
        buttonLearn.setAttribute('href', '/item/' + itemID);
        buttonLearn.classList.add('button-learn');
        buttonLearn.innerHTML = '<img src="https://omeka-s.sewanee.edu/files/asset/40ab43f8a04a70f61edd9cb5dfa1afb2f232f52e.png" alt="Button Learn More">';

        // Create Button See
        const buttonSee = document.createElement('a');
        buttonSee.setAttribute('href', '');
        buttonSee.classList.add('button-see');
        buttonSee.innerHTML = '<img src="https://omeka-s.sewanee.edu/files/asset/c3363c21b14027aaa6c0f7a9d07580da4f8359c7.png" alt="Button See the Interview">';

		const itemButtons = document.createElement('div');
		itemButtons.classList.add('item-buttons');

        item.appendChild(itemButtons);
		
        // Append buttons to the item
        itemButtons.appendChild(buttonLearn);
        itemButtons.appendChild(buttonSee);
      }
    });
  });
</script>

To fill in the href for the buttonSee, I would like to be able to tell it to find the media that corresponds with that item’s ID, that has = (any of these? type = bibo:AudioVisualDocument, class_label = audio-visual document, resource_template_label = Audio/Visual).

I was trying to Fetch it through the API, but haven’t succeeded–I don’t know if I’m doing it wrong, or if it’s a permission/security thing.

Any suggestions?

As for the “mostly works”, it is only showing 10 items, out of 38 that should be popping up. I’ve tried looking in the settings and double-checking that everything has the right class/label/template/item-set, but nothing seems to make it show everything.

Any suggestions for that?

I’ve been able to get part of it to work:

<div class="preview-block clearfix">[items item_set=8]</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
	const items = document.querySelectorAll('.resource.item');

    items.forEach(function(item) {
		const itemThumb = item.querySelector('.resource.item a').firstChild;
		itemThumb.classList.add('item-thumbnail');

		// Extract the item ID from the title link
		const idMatch = item.querySelector('h4 a').getAttribute('href').match(/\/item\/(\d+)/);
		if (idMatch) {
			const itemID = idMatch[1];

            // Find Media-IDs for audio-visual documents
            const mediaID = $.getJSON(`/api/media?item=${itemID}`, function(mediaItems) {
                mediaItems.forEach(function(mediaItem) {
                    if (mediaItem['o:ingester'] === 'youtube') {
                        return mediaItem['o:id'];
                    };
                }); 
            })    
			// Create Button Learn
			const buttonLearn = document.createElement('a');
			buttonLearn.setAttribute('href', '/item/' + itemID);
			buttonLearn.classList.add('button-learn');
			buttonLearn.innerHTML = '<img src="https://omeka-s.sewanee.edu/files/asset/40ab43f8a04a70f61edd9cb5dfa1afb2f232f52e.png" alt="Button Learn More">';

			const buttonSee = document.createElement('a');
			buttonSee.setAttribute('href', '/media/' + mediaID);
			buttonSee.classList.add('button-see');
			buttonSee.innerHTML = '<img src="https://omeka-s.sewanee.edu/files/asset/c3363c21b14027aaa6c0f7a9d07580da4f8359c7.png" alt="Button See the Interview">';

			const itemButtons = document.createElement('div');
			itemButtons.classList.add('item-buttons');

			item.appendChild(itemButtons);
		
			// Append buttons to the item
			itemButtons.appendChild(buttonLearn);
			itemButtons.appendChild(buttonSee);
		}
	});			
});
</script>

It gives me both of my buttons. The first has the correct href, but the second doesn’t. It produces the button, but instead of the item number that I’m looking for, it has [object Object] after the URL that I was trying to fill in. Any suggestions on how to fix that?

With some help from ChatGPT, I was able to fix the code with the buttons, so it is doing what I need. The only question now is why is it only pulling 10 items from my item set? Do I need to make this a different question?

<div class="preview-block clearfix">[items item_set=8]</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', async () => {
    const items = document.querySelectorAll('.resource.item');
    
    for(let item of items) {
        const itemThumb = item.querySelector('.resource.item a').firstChild;
        itemThumb.classList.add('item-thumbnail');

        // Extract the item ID from the title link
        const idMatch = item.querySelector('h4 a').getAttribute('href').match(/\/item\/(\d+)/);
        if (idMatch) {
            const itemID = idMatch[1];
            
            // Fetch Media-IDs for audio-visual documents asynchronously
            let mediaID;
            try {
                const response = await fetch(`/api/media?item=${itemID}`);
                const mediaItems = await response.json();
                for(let mediaItem of mediaItems) {
                    if (mediaItem['o:ingester'] === 'youtube') {
                        mediaID = mediaItem['o:id'];
                        break;
                    }
                }
            } catch (error) {
                console.error('Failed to fetch media items:', error);
                // Handle error appropriately
            }   
            
            if (mediaID) {
                // Create Button See the Interview
                const buttonSee = document.createElement('a');
                buttonSee.setAttribute('href', '/media/' + mediaID);
                buttonSee.classList.add('button-see');
                buttonSee.innerHTML = '<img src="https://omeka-s.sewanee.edu/files/asset/c3363c21b14027aaa6c0f7a9d07580da4f8359c7.png" alt="Button See the Interview">';
                
                // If a media item with a YouTube ingester was found, append the See the Interview button
                const itemButtons = item.querySelector('.item-buttons') || document.createElement('div');
                itemButtons.classList.add('item-buttons');
                itemButtons.appendChild(buttonSee);
                item.appendChild(itemButtons);
            }

            // Create Button Learn More
            const buttonLearn = document.createElement('a');
            buttonLearn.setAttribute('href', '/item/' + itemID);
            buttonLearn.classList.add('button-learn');
            buttonLearn.innerHTML = '<img src="https://omeka-s.sewanee.edu/files/asset/40ab43f8a04a70f61edd9cb5dfa1afb2f232f52e.png" alt="Button Learn More">';

            // Append Learn More button regardless of the mediaID existence
            const itemButtons = item.querySelector('.item-buttons') || document.createElement('div');
            itemButtons.classList.add('item-buttons');
            itemButtons.appendChild(buttonLearn);
            item.appendChild(itemButtons);
        }
    }
}); 
</script>

The items shortcode has a default of retrieving 10 items. The num parameter is used for setting how many you want to get, e.g:

[items item_set=8 num=20]

Facepalm With the number of times I’ve stared at that table, you’d think I would’ve seen that… Thank you!

Ok, never mind it’s not fixed. I could’ve sworn yesterday that each of my buttons was showing a link to a different (and correct) media page. Now, however, they are all leading to the same one. Any suggestions?

The code:

[items item_set=8 num=0 sort=foaf:lastName]

I fixed it! In the fetch /api/media?item=${itemID} it should’ve been /api/media?item_id=${itemID}.

Happy dance.