How to Embed a Facebook Video on Vanilla forum

How do I embed a video from Facebook onto a Vanilla forum?

Comments

  • @R_Jno replies here also

  • Adds iframe code to database, but not displaying data.

  • <iframe src="https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Fsandvik%2Fvideos%2F1055493134654052%2F&amp;show_text=0&amp;width=560" width="560" height="315" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true"></iframe>

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    There is a method in class.format.php which handles embedding videos:


       private static function embedReplacement($url) {
           $embeds = [
               'YouTube' => [
                   'regex' => ['/https?:\/\/(?:(?:www.)|(?:m.))?(?:(?:youtube.com)|(?:youtu.be))\/(?:(?:playlist?)|(?:(?:watch\?v=)?(?P<videoId>[\w-]{11})))(?:\?|\&)?(?:list=(?P<listId>[\w-]*))?(?:t=(?:(?P<minutes>\d*)m)?(?P<seconds>\d*)s)?(?:#t=(?P<start>\d*))?/i']
               ],
               'Twitter' => [
                   'regex' => ['/https?:\/\/(?:www\.)?twitter\.com\/(?:#!\/)?(?:[^\/]+)\/status(?:es)?\/([\d]+)/i']
               ],
               'Vimeo' => [
                   'regex' => ['/https?:\/\/(?:www\.)?vimeo\.com\/(?:channels\/[a-z0-9]+\/)?(\d+)/i']
               ],
               'Vine' => [
                   'regex' => ['/https?:\/\/(?:www\.)?vine\.co\/(?:v\/)?([\w]+)/i']
               ],
               'Instagram' => [
                   'regex' => ['/https?:\/\/(?:www\.)?instagr(?:\.am|am\.com)\/p\/([\w-]+)/i']
               ],
               'Pinterest' => [
                   'regex' => [
                       '/https?:\/\/(?:www\.)?pinterest\.com\/pin\/([\d]+)/i',
                       '/https?:\/\/(?:www\.)?pinterest\.ca\/pin\/([\d]+)/i'
                   ]
               ],
               'Getty' => [
                   'regex' => ['/https?:\/\/embed.gettyimages\.com\/([\w=?&;+-_]*)\/([\d]*)\/([\d]*)/i']
               ],
               'Twitch' => [
                   'regex' => ['/https?:\/\/(?:www\.)?twitch\.tv\/([\w]+)$/i']
               ],
               'TwitchRecorded' => [
                   'regex' => ['/https?:\/\/(?:www\.)?twitch\.tv\/videos\/(\w+)$/i']
               ],
               'Soundcloud' => [
                   'regex' => ['/https?:(?:www\.)?\/\/soundcloud\.com\/([\w=?&;+-_]*)\/([\w=?&;+-_]*)/i']
               ],
               'Gifv' => [
                   'regex' => ['/https?:\/\/i\.imgur\.com\/([a-z0-9]+)\.gifv/i'],
               ],
               'Wistia' => [
                   'regex' => [
                       '/https?:\/\/(?:[A-za-z0-9\-]+\.)?(?:wistia\.com|wi\.st)\/.*?\?wvideo=(?<videoID>([A-za-z0-9]+))(\?wtime=(?<time>((\d)+m)?((\d)+s)?))?/i',
                       '/https?:\/\/([A-za-z0-9\-]+\.)?(wistia\.com|wi\.st)\/medias\/(?<videoID>[A-za-z0-9]+)(\?wtime=(?<time>((\d)+m)?((\d)+s)?))?/i'
                   ]
               ]
           ];
           ...
    
    

    As you can see, facebook isn't on that list. So there is no setting or something you can do on any other way, I'd say. You will need to write your own custom plugin "FacebookVideoEmbed".

    I hate facebook, so I will not be the one who writes such a plugin. But I must confess I have taken a look how it would have to be done.

    I think you should use the fireFilter that is in the processHtml method and by copying much of the Vanilla code you end up with something like this:


       public function format_filterHtml_handler($in, $dummy = []) {
           $linksCallback = function ($matches) {
               static $inTag = 0;
               static $inAnchor = false;
    
               $inOut = $matches[1];
               $tag = strtolower($matches[2]);
    
               if ($inOut == '<') {
                   $inTag++;
                   if ($tag == 'a') {
                       $inAnchor = true;
                   }
               } elseif ($inOut == '</') {
                   $inTag++;
                   if ($tag == 'a') {
                       $inAnchor = false;
                   }
               } elseif ($matches[3]) {
                   $inTag--;
               }
    
               if (!isset($matches[4]) || $inTag || $inAnchor) {
                   return $matches[0];
               }
    
               // We are not in a tag and what we matched starts with //
               if (preg_match('#^//#', $matches[4])) {
                   return $matches[0];
               }
    
               $url = $matches[4];
               list($width, $height) = Gdn_Format::getEmbedSize();
    
               $urlParts = parse_url($url);
               if ($urlParts['host'] != 'www.facebook.com' && $urlParts['scheme'] != 'https') {
                   return $url;
               }
    
               $queryString = $urlParts['query'] ?? '';
               parse_str($queryString, $query);
               // There's the possibility the query string could be encoded, resulting in parameters that begin with "amp;"
               foreach ($query as $key => $val) {
                   $newKey = stringBeginsWith($key, 'amp;', false, true);
                   if ($newKey !== $key) {
                       $query[$newKey] = $val;
                       unset($query[$key]);
                   }
               }
    // Everything needed is now available in $query or $urlParts['path']. Transmogrify it and return that bloated html
               return 'Facebook ist Käse';
           };
    
           if (unicodeRegexSupport()) {
               $regex = "`(?:(</?)([!a-z]+))|(/?\s*>)|((?:(?:https?|ftp):)?//[@\p{L}\p{N}\x21\x23-\x27\x2a-\x2e\x3a\x3b\/\x3f-\x7a\x7e\x3d]+)`iu";
           } else {
               $regex = "`(?:(</?)([!a-z]+))|(/?\s*>)|((?:(?:https?|ftp):)?//[@a-z0-9\x21\x23-\x27\x2a-\x2e\x3a\x3b\/\x3f-\x7a\x7e\x3d]+)`i";
           }
    
           $out = Gdn_Format::replaceButProtectCodeBlocks(
               $regex,
               $linksCallback,
               $in,
               true
           );
    
           return $out;
       }
    



  • I am not that much expertise into this, I have found the function in class.format.php , but i m not able to figure out , how to proceed to fix this issue.

    kindly help me out on this.

  • charrondevcharrondev Application Developer (PHP, JS) Montreal Vanilla Staff

    @R_J that embed replacement code is what we have for Advanced Editor posts. Rich editor has a different pipeline and support for more embeds.

    This issue was just moved into our planning pipeline, and I think the extendable new Rich embed system (with documentation and examples) will be ready for the 3.1 release.

    Another ongoing goal (definitely this year, although the exact month will depend on how successful our hiring is right now. We're hiring a bunch of developers at the moment) is the refactoring & unification of our content rendering pipelines. That would bring some additional configuration options and administration pages.

    Shadowdaredivyesh_joshi19
  • ShadowdareShadowdare Moderator
    edited May 24

    Like @R_J, mentioned, you'd have to create your own plugin to add support for Facebook embeds by taking the formatted output of discussion/comment bodies and replacing links to Facebook videos with its embed code.

    I've actually put together a prototype addon to add support for various video site embeds, but haven't done much with it. I added a base_links_handler and used Gdn_Format::replaceButProtectCodeBlocks(). It was mainly just an experiment of Garden Container's DI where developers can just drop in class files in a folder to add more sites, instead of tightly coupling the embed logic for each site in the addon's main code. This was probably over-engineered, though. 😂

    Rather, would the new embed system (EmbedManager) only be for the Rich Editor, or an extension to formatting in general for any format that would provide the ability to add more sites, @charrondev?

    Add Pages to Vanilla with the Basic Pages app

    divyesh_joshi19
Sign In or Register to comment.