Video slug from ID
-
With javascript how can I retrieve the SLUG of a video from his ID ?
Thanks for reply
-
Hi @jarthex,
Great question! You can retrieve the slug of a video by its ID using the WordPress REST API via JavaScript. Since our videos use the custom post type
aiovg_videos, here’s how you can do it:async function getVideoSlugById(videoId) { const response = await fetch(/wp-json/wp/v2/aiovg_videos/${videoId}); if (!response.ok) { throw new Error(Failed to fetch video: ${response.statusText}); } const video = await response.json(); return video.slug; } // Usage example: getVideoSlugById(123) .then(slug => console.log('Video slug:', slug)) .catch(error => console.error('Error:', error));How it works:
- It calls the WordPress REST API endpoint for the
aiovg_videoscustom post type using the video’s ID. - The API returns the post object, from which we extract the
slugproperty.
Hope this helps! Feel free to reach out if you have any further questions.
Thanks. I’ll test that.
Another question. Always in JavaScript (or jQuery preferably). How can I retrieve the list of all slugs?
It works well after correcting syntax errors. For the question about the list of SLUGS, also include the SLUG and its associated ID.
Hi @jarthex, glad it’s working!
Here’s how to retrieve all video slugs and IDs using the WordPress REST API:
jQuery version:
function getAllVideoSlugs() { return $.ajax({ url: '/wp-json/wp/v2/aiovg_videos', data: { per_page: 100, _fields: 'id,slug' } }).then(function(videos) { return videos.map(function(video) { return { id: video.id, slug: video.slug }; }); }); } // Usage: getAllVideoSlugs() .done(function(results) { console.log(results); }) .fail(function(err) { console.error('Error:', err); });Vanilla JS version (with pagination):
async function getAllVideoSlugs() { const results = []; let page = 1; let totalPages = 1; while (page <= totalPages) { const response = await fetch(/wp-json/wp/v2/aiovg_videos?per_page=100&_fields=id,slug&page=${page}); if (!response.ok) throw new Error(Request failed: ${response.statusText}); totalPages = parseInt(response.headers.get('X-WP-TotalPages'), 10) || 1; const videos = await response.json(); videos.forEach(v => results.push({ id: v.id, slug: v.slug })); page++; } return results; } // Usage: getAllVideoSlugs() .then(results => console.log(results)) .catch(err => console.error('Error:', err));A couple of things worth noting:
- The
_fields=id,slugparameter keeps the response lightweight by only fetching what you need. - The WordPress REST API returns a maximum of 100 items per page. If you have more than 100 videos, the vanilla JS version handles pagination automatically using the
X-WP-TotalPagesresponse header. The jQuery version above assumes fewer than 100 videos.
Hope this helps! Feel free to ask if you run into anything.
I managed to implement this function and it works well. I just had to modify functions.php to avoid a 401 error. Thanks again 🙂
If I’m not mistaken, /videos-catalogue/ is generated by the plugin. Is there a way to modify this page in WordPress? When /videos-catalogue/ is accessed on its own, it redirects to /videos-catalogue-all/. I created this page in WordPress and modified it; it works.
Hi @jarthex, great to hear it’s all working — and good thinking on the
functions.phpfix for the 401!Regarding the
/videos-catalogue/page — just to clarify, our plugin doesn’t actually create that slug by default. It only appears if you’ve either overridden the default archive slug in the plugin’s settings, or configured a custom videos archive page.The redirect to
/videos-catalogue-all/is a bit puzzling without more context. Could you share the full URL? That way we can take a direct look and get a better idea of what’s happening on your end.Looking forward to helping you sort this out!
Here is my website https://metz-aikido.fr/
In the menu click on MEDIAS and VIDEOS CATALOGUE.
for each VIDEO. Click on 🔗 display /videos-catalogue/ for this VIDEO
Result by example
https://metz-aikido.fr/videos-catalogue/les-kumijo-1-5-de-saitoTo view the HTML code (right-click and inspect), click on SHIMASU in the footer and reload the page.
HERE IS MY CODE
FUNCTION.PHP
============
add_action('wp_ajax_get_all_video_slugs', 'ajax_get_all_video_slugs');
add_action('wp_ajax_nopriv_get_all_video_slugs', 'ajax_get_all_video_slugs');
function ajax_get_all_video_slugs() {
$args = array(
'post_type' => 'aiovg_videos',
'posts_per_page' => -1, // <--- Le "-1" magique qui récupère TOUS les éléments d'un coup
'post_status' => 'publish',
'fields' => 'ids', // Performance : on ne demande d'abord que les IDs pour alléger la requête
);
$video_ids = get_posts($args);
$results = array();
if (!empty($video_ids)) {
foreach ($video_ids as $id) {
$results[] = array(
'id' => $id,
'slug' => get_post_field('post_name', $id)
);
}
}
if (!empty($results)) {
wp_send_json_success($results);
} else {
wp_send_json_error('Aucune vidéo trouvée');
}
}
@SLUG HTML TEMPLATE TO SET WITH gCo_ns_C.Array_SLUG ({id:,slug:})
==========================================================
GLB_ns_H.VIDEO_DIV_YOUTUBE_AIOVG_Template =<br> <div class="gj-video-div gj-video-div-aiovg"><br> <p class="gj-video-icones"><br> <a title="Afficher en pleine page"<br> class="gj-link gj-video-full-page"<br> href="${GLB_ns_C.Youtube_Embed}/@URL"<br> data-id="@SLUG"<br> target="_blank"<br> ><br> <a title="Catalogue"<br> class="gj-link gj-video-catalogue"<br> href="${/${GLB_ns_C.Obj_Pages.Videos_Catalogue}/}@SLUG"<br> ><br> </a><br> <a class="aiovg gj-video-expand gj-video-expand-extend" title="Etendre la video"<br> data-id="@SLUG"<br> ><br> </a><br> </p><br> ${GLB_ns_H.VIDEO_IMAGE_Template}<br> </div><br>
;
SET HTML WITH THE TABLE gCo_ns_C.Array_SLUG ({id:,slug:})
======================================================
const _laiovg_item_videoCLASS = $('.aiovg-item-video');
if (Fnative.length(_laiovg_item_videoCLASS)) {
gCo_ns_X.Maiovg.Set_aiovg_item_video();
gCo_ns_X.Maiovg.Get_AllVideos_SLUG();
// Attente gCo_ns_C.Array_SLUG {id:,slug:}
// soit rempli par gCo_ns_X.Maiovg.Get_AllVideos_SLUG()
let ltimer = 0;
let laiovg_CheckState =
setInterval(() => {
++ltimer;
// STOP
if (ltimer > GLB_ns_C.Obj_Psite.Timer_Interval_Max) {
Fnative.console_color({
message:\n${gCo_ns_C.From} STOP INTERVAL laiovg_CheckState pour gCo_ns_C.Array_SLUG\n,
important: true
});
clearInterval(laiovg_CheckState);
}
if (Fnative.length(gCo_ns_C.Array_SLUG) > 0) {
clearInterval(laiovg_CheckState);
// Tri par id
gCo_ns_C.Array_SLUG.sort((a, b) => a.id - b.id);
// Html @SLUG
gCo_ns_X.Maiovg.Set_aiovg_item_video_SLUG();
}
// END setInterval
}, 100);
}
FUNCTION Get_AllVideos_SLUG CREATION OF THE TABLE gCo_ns_C.Array_SLUG ({id:,slug:})
==================================================================================
Get_AllVideos_SLUG: async () => {
// console.log('Get_AllVideos_SLUG');
try {
const response = await $.ajax({
url: '/wp-admin/admin-ajax.php',
method: 'POST',
data: { action: 'get_all_video_slugs' }
});
if (!response.success) {
throw new Error(response.data);
}
// On stocke DIRECTEMENT le résultat dans votre tableau global
gCo_ns_C.Array_SLUG = response.data;
// console.log('Tableau "SLUG_Array" mis à jour ! Nombre d\'éléments :', gCo_ns_C.Array_SLUG.length);
} catch (erreur) {
// Le .fail() est remplacé par ce catch qui attrape toutes les erreurs (AJAX ou PHP)
console.error('Erreur lors de la récupération des slugs :', erreur);
}
},
FUNCTION Set_aiovg_item_video_SLUG (replace @SLUG from gCo_ns_C.Array_SLUG)
==========================================================================
Set_aiovg_item_video_SLUG: () => {
console.log('Set_aiovg_item_video_SLUG');
// console.log('gCo_ns_C.Array_SLUG : '+JSON.stringify(gCo_ns_C.Array_SLUG));
let lID;
let lfound;
let lfoundindex;
let lindex;
let lhtml;
const _laiovg_item_videos = $('.aiovg-item-video');
let _lvideos_icones;
let llength = Fnative.length(gCo_ns_C.Array_SLUG);
for (const lelement of _laiovg_item_videos) {
_lvideos_icones = $(lelement).find('.gj-video-icones');
lID = Fjquery._attr({type:'get', element:lelement, attr:['data-id']});
lfound = gCo_ns_C.Array_SLUG.find(el => el.id === Number(lID));
lhtml = Fjquery._html({type:'get',element:_lvideos_icones});
lhtml =
Fnative.replace(
lhtml,
['@SLUG', lfound.slug, 1]
);
Fjquery._html({type:'set',element:_lvideos_icones,html:lhtml});
}
},Hi @jarthex, thanks for sharing all of this — very clear and well-organised!
We had a look at your site. The
/videos-catalogue/slug is actually working correctly — it’s the archive page generated by our plugin for theaiovg_videoscustom post type. The individual video URLs likehttps://metz-aikido.fr/videos-catalogue/les-kumijo-1-5-de-saitoare the single post permalinks for each video, which is the expected behaviour.Regarding the redirect to
/videos-catalogue-all/you mentioned earlier — we couldn’t reproduce it from our end. It’s possible it was a temporary conflict or has since been resolved. If it happens again, do let us know!To answer your original question — yes, you can absolutely modify the
/videos-catalogue/page in WordPress. Here’s how to set it up properly so you can edit it like any other page:- In WordPress, create a new page with the slug
videos-catalogue(Pages → Add New, and set the permalink/slug tovideos-catalogue). - Go to Video Gallery → Settings → Advanced (tab) → Pages & Permalinks (submenu).
- Click on the Permalinks & Archive Settings accordion.
- In the Video Archive Page field, select the page you just created.
- Save the changes.
Once that’s done, the plugin will use your custom page as the archive, and you can edit its content freely from the WordPress editor.
If you run into a 404 error after this, it’s usually because WordPress needs to refresh its rewrite rules. To flush them:
- Go to Settings → Permalinks.
- Without changing anything, just click Save Changes at the bottom.
That should resolve any 404 issues immediately.
On your code side — we can see you’ve taken a smart approach by using a PHP
admin-ajax.phpendpoint infunctions.phpinstead of the REST API, which explains why you avoided the 401. The logic for fetching all slugs, sorting by ID, and then replacing@SLUGplaceholders in your HTML template is clean and well thought out. Nice work!Just one small note: the polling interval approach with
setIntervalworks well, but since yourGet_AllVideos_SLUGfunction is alreadyasync, you could alternativelyawaitit directly before runningSet_aiovg_item_video_SLUG, which would simplify the timing logic:await gCo_ns_X.Maiovg.Get_AllVideos_SLUG(); gCo_ns_C.Array_SLUG.sort((a, b) => a.id - b.id); gCo_ns_X.Maiovg.Set_aiovg_item_video_SLUG();That said, if your current implementation is working well, there’s no urgent need to change it.
Feel free to reach out if anything else comes up!
Version issue? I don’t have Video Gallery → Settings → Advanced (tab) → Pages and Hyperlinks (submenu).Permalinks & Archive Settings accordion.
I don’t fully understand the concept of related videos. What criteria are used to find the videos linked in the example http://budokai-metz-aikido.test/videos-catalogue/01-202604-suga-vire-yokomen-uchi-kote-gaeshi
Hi @jarthex,
- Settings menu — Yes, that’s a version issue. We completely restructured the plugin’s settings menu for improved clarity and navigation in version 4.8.5. Could you update to the latest version of All-in-One Video Gallery? Once updated, you’ll find the Advanced → Pages & Permalinks → Permalinks & Archive Settings path as described.
- Related videos — These are videos that share the same categories and/or tags as the currently playing video. So in your example, the related videos shown are other videos in your library that have at least one category or tag in common with
01-202604-suga-vire-yokomen-uchi-kote-gaeshi. You can manage these from each video’s edit screen in WordPress by adjusting its assigned categories and tags.
Let us know how the update goes!
I updated to the latest version. I created the MEDIAS/VIDEOS CATALOGUE page and added this page in Advanced → Pages & Permalinks → Permalinks & Archive Settings. It works (for example, http://budokai-metz-aikido.test/medias/videos-catalogue/jo-kihon), but if I edit the /MEDIAS/VIDEO CATALOGUE page (with Elementor), these changes don’t appear (??).
Regarding related videos, I have videos with the same tag but different categories. I assume there’s no way to select only related categories. I can do this selection in my code. To do this, I’ll modify my function.php to retrieve the category for each ID. Any thoughts?
FUNCTION.PHP
=============
add_action('wp_ajax_get_all_video_slugs', 'ajax_get_all_video_slugs');
add_action('wp_ajax_nopriv_get_all_video_slugs', 'ajax_get_all_video_slugs');
function ajax_get_all_video_slugs() {
$args = array(
'post_type' => 'aiovg_videos',
'posts_per_page' => -1, // <--- Le "-1" magique qui récupère TOUS les éléments d'un coup
'post_status' => 'publish',
'fields' => 'ids', // Performance : on ne demande d'abord que les IDs pour alléger la requête
);
$video_ids = get_posts($args);
$results = array();
if (!empty($video_ids)) {
foreach ($video_ids as $id) {
$results[] = array(
'id' => $id,
'slug' => get_post_field('post_name', $id)
);
}
}
if (!empty($results)) {
wp_send_json_success($results);
} else {
wp_send_json_error('Aucune vidéo trouvée');
}
}oups… the url is https://metz-aikido.fr/medias/videos-catalogue/jo-kihon
I’ve solved my problem with RELATED VIDEOS. I set a large value in the Limit-per-page parameter to display the complete list of RELATED VIDEOS. I then remove videos from this list that don’t have the same category as the video in the PLAYER. I also remove the pagination, which is now unnecessary.
Hi @jarthex, glad the update went smoothly, and great work figuring out the related videos issue on your own! 🙂
About editing the page with Elementor:
The changes you make to the
/medias/videos-catalogue/page with Elementor will apply to the archive page itself (the gallery listing), but not to the single video pages like/medias/videos-catalogue/jo-kihon. Those are handled separately by the plugin.Also, please make sure the archive page includes the
[aiovg_videos]shortcode somewhere in its content — that shortcode is what actually renders the gallery. Without it, the archive won’t display correctly.If you want to customize the single video pages too:
If you’re using Elementor Pro, you can fully customize the video detail pages using Elementor’s Theme Builder. Here’s a tutorial that walks through it:
📺 Watch Tutorial: https://www.youtube.com/watch?v=8Fk-Edu7DL0
Once your template is designed, be sure to select “Videos” under the “Where Do You Want to Display Your Template?” section:
🔗 Skip to this part: https://youtu.be/8Fk-Edu7DL0?t=130
A few important notes:
- To display the video dynamically on each detail page, use the shortcode
[aiovg_video]. This will automatically load the correct video based on the current post. - The Related Videos section is automatically removed from custom video detail pages. If you want to display it, just add the shortcode
[aiovg_related_videos]wherever you’d like it to appear in your layout. - If the shortcodes don’t work properly inside Elementor, add the following to the bottom of your theme’s
functions.php:
add_filter( 'aiovg_the_content_in_the_loop', __return_true );add_filter( 'aiovg_the_content_is_main_query', __return_true );That’s it. This should give you full control over the styling and structure of both your archive and single video pages.
Let us know if you run into anything!
-
This reply was modified 1 month, 1 week ago by
San Rosh.
- It calls the WordPress REST API endpoint for the
You must be logged in to reply to this topic.