How would you suggest I validate an URL provided in a url field in the panel, to see if it will work with Html::video() ?
Ideally this would validate in the panel, but could validate in the template.
In my particular case I was doing:
<?php if($page->video()->isNotEmpty()): ?>
<?= Html::video($page->video()) ?>
<?php else: ?>
...
…if the validation is done here, ideally I would do:
<?php if($page->video()->isNotEmpty() && /* URL is valid youtube/vimeo */): ?>
<?= Html::video($page->video()) ?>
<?php else: ?>
...
Thank you
Good question! The list of possible YouTube patterns is pretty long: https://github.com/getkirby/kirby/blob/dbd7fa7f303e7045626adb72c5f0b29c6ccadb44/src/Toolkit/Html.php#L472
For Vimeo it’s not as much stuff: https://github.com/getkirby/kirby/blob/dbd7fa7f303e7045626adb72c5f0b29c6ccadb44/src/Toolkit/Html.php#L434
But rather then validating, it would probably make more sense to catch the exception in your code and return nothing for visitors while displaying an error message for logged in users?
Thank you @texnixe,
That’s absolutely right.
Perhaps I could write a small function with a try catch block that attempts Html::video() with the passed url, and returns false if it catches an exception. Then use it as a condition in that if() ?
function checkVideoUrl($url) {
try {
Html::video($url);
return true;
} catch (Exception $e) {
return false;
}
}
then
<?php if($page->video()->isNotEmpty() && checkVideoUrl($page->video())): ?>
<?= Html::video($page->video()) ?>
<?php else: ?>
...
Thanks
Hm, but that way, you use Html::video()
twice for no reason, better put the try/catch block directly into your template or - if you want to use that function, then return the video from your function.
But how would you suggest I do the flow control so I jump to the else
block if either $page->video() is empty or Html::video returns an exception, without repeating the else
block code twice, once in the try
, and again in the else
?
Danke
Either like this (but then the name of the function is a bit off):
function checkVideoUrl($url) {
try {
return Html::video($url);
} catch (Exception $e) {
return 'An error occurred';
}
}
if($page->video()->isNotEmpty()) {
echo checkVideoUrl( $page->video() );
}
Or without the function:
if($page->video()->isNotEmpty()) {
try {
echo Html::video($page->video());
} catch (Exception $e) {
echo 'An error occurred';
}
}
Thanks again,
Perhaps I am not understanding or did not explain myself well.
What I would like to do is :
// If $page->video()->isNotEmpty()
// try
// Html::video($page->video())
// catch (Exception $e)
// $mycodeblock
// else
// $mycodeblock (the same code)
$mycodeblock there being a rather lentghy html+kirby php code block
Is that perhaps clearer ?
This would be the real code, using my redundant function solution:
<div class="inner left">
<?php if($page->video()->isNotEmpty() && checkVideoUrl($page->video())): ?>
<div class="video-wrapper">
<?= Html::video($page->video()) ?>
</div>
<?php else: ?>
<img class="doublearrowright" src="<?= asset('assets/img/double_arrow_right.svg')->url()?>" alt="Double arrow right">
<div class="swiper-container evento-publico">
<div class="swiper-wrapper evento-publico">
<?php foreach ( $page->images()->sortBy('sort', 'asc') as $img ): ?>
<div class="swiper-slide evento-publico">
<div class="slide-wrapper">
<div class="cover-img" style="background-image: url('<?= $img->resize(800)->url() ?>'); background-position: center center; background-size: cover"></div>
<div class="caption"><?= $img->caption() ?></div>
</div>
</div>
<?php endforeach ?>
</div>
</div>
<div class="swiper-container evento-publico-thumbs">
<div class="swiper-wrapper">
<?php foreach ( $page->images()->sortBy('sort', 'asc') as $img ): ?>
<div class="swiper-slide cover-img" style="background-image: url('<?= $img->resize(800)->url() ?>'); background-position: center center; background-size: cover"></div>
<?php endforeach ?>
</div>
</div>
<?php endif ?>
Thank you
Hm, I don’t understand what the problem is.
<div class="inner left">
<?php if($page->video()->isNotEmpty()): ?>
<div class="video-wrapper">
<?php try {
echo Html::video($page->video());
} catch (Exception $e) {
echo 'An error occurred'; // or just empty string or conditionally whether user is logged in
}
?>
</div>
<?php else: ?>
<!-- rest of block -->
<?php endif ?>
sorry, forgot to remove the function call, edited.
The problem would be how to load the same block of code ($mycodeblock in my pseudocode above) if $page->video() is empty BUT ALSO if $page->video() is not empty BUT Html::video() returns an exception.
Again, to load the same code in both cases.
As far as I understand it, in your last code, if $page->video() is not empty BUT Html::video() throws an exception, the else
block will NOT be loaded, which is precisely what I am attempting.
No, why should the else block not be executed? If you put the rest of the block into the catch part, you will end up with the same stuff twice, which makes no sense whatsoever.
…because it only executes if $page->video() is empty ?
The expected behaviour is:
// If the editor provided a video url AND the video url is a valid url
// load the video
// if the editor did not provide a video url OR the video url is not a valid url
// load images instead
Ah, ok, I am a bit slow on the uptake tonight.
Then put the stuff after else
into a snippet and call it inside the catch
part instead of showing the error and after the else.
<div class="inner left">
<?php if($page->video()->isNotEmpty()): ?>
<div class="video-wrapper">
<?php try {
echo Html::video($page->video());
} catch (Exception $e) {
snippet('images');
}
?>
</div>
<?php else: ?>
<?php snippet('images') ?>
<?php endif ?>
Ok, thank you @texnixe for this solution.
Have a good night.