requarks / wiki

Wiki.js | A modern and powerful wiki app built on Node.js
https://js.wiki
GNU Affero General Public License v3.0
24.36k stars 2.69k forks source link

WYSIWYG editor: "Insert media" not displaying embedded content in front-end #1139

Open carloposo opened 4 years ago

carloposo commented 4 years ago

Actual behavior

Embedded media (for example, a YouTube or Vimeo video) is correctly shown in WYSIWYG editor, but it is not in the final page (front-end).

Expected behavior

Embedded media is shown in the front-end.

Steps to reproduce the behavior

  1. edit a page
  2. click on "Insert media" icon in top bar
  3. paste URL of video (for example https://vimeo.com/243244233)
  4. see video preview in the page
  5. click "Save" (top right of page)
  6. click "Close" (top right of page)
  7. the video is not present in the page
anibal-aguila commented 4 years ago

same issue here

ideasandpixels commented 4 years ago

Same issue here. Looks like a very old issue -- any ideas?

nideKer commented 4 years ago

Same issue here. Is there any chance to fix it?

mrUlrik commented 3 years ago

I thought this was perhaps related to security settings such as embedding IFrame found in Admin > Security > Block IFrame Embedding or perhaps some kind of Cross-Site security issue. But after seeing no errors Console or Network I see that the rendered document simply doesn't include any information in the <figure> tag despite the fact that it shows at least a thumbnail of the content in the WYSIWYG editor.

The example below was created with a random Youtube video. The WYSIWYG editor displayed the video's thumbnail properly, but it's never rendered on the actual page.

<div>
    <p>Media Content Test, Media should appear below here</p>
    <div></div>
    <figure class="media"></figure>
    <div></div>
    <p>Media Content Test, Media should appear above here</p>
</div>
mtrip commented 3 years ago

Same issue

ryanmasuga commented 3 years ago

We just installed Wiki.js and the first thing I tried was embedding a YouTube video on a WYSIWYG page and I immediately ran into this. This has been open nearly a year at this point.

According to this other issue (https://github.com/Requarks/wiki/issues/1459), from Feb 2020 "Videos are not yet supported in the rendering pipeline." Maybe this issue should be closed if the most up-to-date discussion about it is over there.

TheBigShort111 commented 3 years ago

Feb 24 2021 - Same issues here

Jsmithrud37 commented 3 years ago

Running into this as well.

radialbalance commented 3 years ago

Same! I tried changing the Santize HTML & Rendering Security, but still no luck.

MaxWaldorf commented 3 years ago

Would like to see this feature fully implemented as well...

Cheers

grandixximo commented 3 years ago

Credits to @NGPixel @stukev and @BitWiseSE

for who did not follow the conversation over in the other bug report #1459

DISABLE rendering => HTML => security => Sanitize HTML

add this in your theme CSS Override

@media only screen and (max-width:640px) {
    .video-responsive {
        position: relative;
        padding-bottom: 56.25%;
        height: 0;
    }
    .video-responsive iframe {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }
    .video-responsive video {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }
}

and this to your HTML injection

<script type="text/javascript" defer>
window.boot.register('vue', () => {
    window.onload = function InteractiveVideos() {
        document.querySelectorAll('oembed, a').forEach(elm => {
            if (elm.hasAttribute('url')) { url = elm.getAttribute('url') } else { url = elm.getAttribute('href') }
            newElm = document.createElement('div')
            newElm.classList.add('video-responsive')            
            rx = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/;
            if (url.match(rx)) {
                newElm.insertAdjacentHTML('beforeend', `<iframe id="ytplayer" type="text/html" width="640" height="360" src="https://www.youtube.com/embed/${url.match(rx)[1]}" frameborder="0" allowfullscreen></iframe>`)
                elm.replaceWith(newElm)
            }
            rx = /^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/))?([0-9]+)/;
            if (url.match(rx)) {
                newElm.insertAdjacentHTML('beforeend', `<iframe id="vmplayer" type="text/html" width="640" height="360" src="https://player.vimeo.com/video/${url.match(rx)[5]}" frameborder="0" allowfullscreen></iframe>`)
                elm.replaceWith(newElm)
            }
            rx = /^(.*\.(?:(mp4)$))/;
            if (url.match(rx)) {
                newElm.insertAdjacentHTML('beforeend', `<video controls autostart="0" name="media" width="640" height="360"><source src="${url.match(rx)[1]}" type="video/mp4"></video>`)
                elm.replaceWith(newElm)
            }
        })
    }
})
</script>

This will embed Youtube Vimeo and local mp4 in your WYSIWYG pages. How it works: It scans your page once after it's fully loaded, it finds the 'broken' tags, and mp4 links, and substitutes them with iframes and videos tags that display 640x360 embedded video if sanitize HTML is disabled. The CSS makes the videos fit on mobile screens, use at your own discretion.