2014年9月14日 星期日

Discuz! X3.1 自製youtube內嵌影片 discuz!代碼,自動提出YouTube ID

Discuz!X 3.1論壇編輯器並沒有支持YouTube影片的插入功能

就算使用後台新增自定義 discuz!代碼 也要使用者能分辨出youtubeID參數,非常不人性化

很容易搞錯,也不好教學,因為與朋友共同管理的論壇需要這項功能

上網找了一些資料發現可以通過修改論壇的檔案來實現自製的編輯器功能選單

於是龍花了好幾天完成了自定義功能的實作

功能:

  • 自動提出youtube影片ID
  • 支持youtube短網址
  • 支持帶有list參數的播放清單影片連結
  • 可選擇  偏左,置中,偏右  等排版方式
  • 支持選擇 預先定義好的影片尺寸 或是 自定義影片尺寸
  • 可選擇是否加入  自動播放,影片開始時間,默認高畫質,禁用全螢幕鈕  等參數




適用於Discuz!X3.1,其他版本龍並不清楚能不能相容,如果相容的話請告知謝謝!



請先下載這張icon:

上傳到論壇的static/image/common/裡

這張圖將會作為按鈕圖標使用

到Discuz論壇的管理中心找到「界面 > 編輯器設置 > Discuz! 代碼

新增 一個新的標籤 "YT",在"圖標文件 / 描述"這一欄位填入 YTicon.png

提交之後進一步填入這些設定

  • 替換內容:
    <div {2}>
      <iframe {1} src="//www.youtube.com/embed/{3} " frameborder="0" allowfullscreen></iframe>
        </div>
        • 參數個數: 3

        • 嵌套次數: 1

        • 允許使用此代碼的用戶組: 這裡請自行選擇可以使用到此discuz代碼的用戶組!
        送出保存

        可以去編輯器查看,此時會出現我們剛剛自定義的代碼功能按鈕




        接下來要修改/static/js/editor.js檔案(在這之前請先做好備份,如果出問題的話可以還原檔案)

        請找到case 'index':

        在editor.js裡頭會有兩處

        請在第一處前面一行插入這些程式碼:

        /*修改者:鐳鍶龍
        自訂義[YT]標籤的編輯器選單
        用途:產生選單
        */
        case'YT':
        //選單樣式設定
        stitle = '插入youtube影片';
        stitle = '插入youtube影片';
        str = '<form id="' + ctrlid + '_menu_content"><input type="text"  id="' + ctrlid + '_url" '+( selection ?  ' value="' + selection + ' "' : '' )+ 'onclick=\' funSetInner( "' + ctrlid +'_info_url" , "請輸入youtube影片網址" ) \'  ' +' placeholder="http://www.youtube.com,http://youtu.be...等" style="width:65%;margin-bottom:5px; display:inline-block;" class="px"><span id="' + ctrlid + '_info_url" style="margin-left:5px; width: 30%; color:gray;">請輸入youtube影片網址</span><br><span  style="margin-bottom:5px; display:inline-block;"><label><input type="radio"  name="align" value="left" checked>向左對齊</label><label><input type="radio"  name="align" value="middle" >置中</label><label><input type="radio"  name="align" value="right" >向右對齊</label></span><br><label  style="cursor:pointer;" onclick=\'funSetUpDown("' + ctrlid +'_menu_s_t");funSetHiseShow("' + ctrlid +'_menu_content_size");\'><span style="margin-bottom:5px; display:inline-block;"><b>影片大小</b></span><span  id="' + ctrlid +'_menu_s_t" style="padding-left:5px">▽</span></label><br><div id ="' + ctrlid +'_menu_content_size" style="display:none;"><label><input type="radio"  name="YTsize"  value="420x315" checked>420x315</label><br><label><input type="radio"  name="YTsize"  value="480x360">480x360</label><br><label><input type="radio"  name="YTsize"  value="640x480">640x480</label><br><label><input type="radio"  name="YTsize"  value="640x360">640x360</label><br><label><input type="radio"  name="YTsize"  value="853x480">853x480</label><br><label><input type="radio"  name="YTsize"  value="1280x720">1280x720</label><br><label><input type="radio"  name="YTsize"  value="custom">自訂:<input type="text"  id="' + ctrlid + '_width"  '+ 'onclick=\' funSetInner( "' + ctrlid +'_info_size" , "" ) \'  ' +'  size="4" class="px">x<input type="text"  id="' + ctrlid + '_height"   '+ 'onclick=\' funSetInner( "' + ctrlid +'_info_size" , "" ) \'  ' +'  size="4" class="px"></label><br><span id = "' + ctrlid + '_info_size" style="margin-left:63Px;color:red;" ></span></div><label  style="cursor:pointer;" onclick=\'funSetUpDown("' + ctrlid +'_menu_a_t");funSetHiseShow("' + ctrlid +'_menu_content_adv");\'><span style="margin-bottom:5px; display:inline-block;"><b>進階</b></span><span id="' + ctrlid +'_menu_a_t" style="padding-left:5px">▽</span></label><br><div  id="' + ctrlid +'_menu_content_adv"  style="display:none;"><label><input type="checkbox"   name="adv" value="start">撥放器開始時間:<input type="text"  id="' + ctrlid + '_adv_t_h"  '+' onclick=\' $("'+ctrlid + '_menu_content").adv[0].checked=true\' '+'  size="3">小時<input type="text"  id="' + ctrlid + '_adv_t_m"  '+' onclick=\' $("'+ctrlid + '_menu_content").adv[0].checked=true\' '+'  size="2">分<input type="text"  id="' + ctrlid + '_adv_t_s"  '+' onclick=\' $("'+ctrlid + '_menu_content").adv[0].checked=true\' '+'  size="2">秒</label><br> <label><input type="checkbox"   name="adv" value="hd=1">默認高畫質</label><br> <label><input type="checkbox"   name="adv" value="fs=0">禁止全螢幕</label><br> <label><input type="checkbox"   name="adv" value="autoplay=1">自動撥放</label> </div></form>';
        menuwidth = 500;
        menupos = '00';
        menutype = 'win';
        break;
        //----自訂義[YT]標籤編輯器選單-----結束---------------------------------


        接著在第二處的前面一行插入另一段程式碼 :

        /*修改者:鐳鍶龍
        自訂義[YT]標籤的編輯器選單
        用途:資料處理
        */
        case 'YT':
        //影片參數
        var YTid; //YoutubeID
        var YTarg = ""; //內嵌影片參數
        //檢測url是否正確&提出YoutubeID
        if(trim($(ctrlid +'_url').value)==""){
        $(ctrlid + '_info_url').innerHTML="<b>請輸入網址!</b>";
        $(ctrlid + '_info_url').style.color="red";
        $(ctrlid + '_url').select();
        $(ctrlid + '_url').blur();
        $(ctrlid + '_url').focus();
        return;
        } else if (!(YTid =  getYTid(trim($(ctrlid +'_url').value)) ? getYTid(trim($(ctrlid +'_url').value))[0] : false)){
        $(ctrlid + '_info_url').innerHTML="<b>網址錯誤!請重新輸入!</b>";
        $(ctrlid + '_info_url').style.color="red";
        $(ctrlid + '_url').select();
        $(ctrlid + '_url').blur();
        $(ctrlid + '_url').focus();
        return;
        }
        //提出內嵌影片參數
        //提出list參數
        if(YTlist = getYTid(trim($(ctrlid +'_url').value))[1]) YTarg += '&list='+ YTlist;
        //提出選單進階參數
        for( var i=0; i < $(ctrlid + '_menu_content').adv.length; i++) {
        tmpAdvCheckbox =$(  ctrlid + '_menu_content').adv[i];
        if(tmpAdvCheckbox.checked) {
        //針對t參數作處理
        if(tmpAdvCheckbox.value == "start"){
        tmpAdvTh = trim($(ctrlid + '_adv_t_h' ).value);
        tmpAdvTm = trim($(ctrlid + '_adv_t_m' ).value);
        tmpAdvTs = trim($(ctrlid + '_adv_t_s' ).value);
        if( !( /\D+/.test(tmpAdvTs) ||  /\D+/.test(tmpAdvTm) ||  /\D+/.test(tmpAdvTh))  ){
        YTarg += "&start=" + (tmpAdvTs + tmpAdvTm*60 + tmpAdvTh*60*60);
        }else{
        showDialog("進階參數:\"撥放器開始時間\"<br>請不要填入非數字字元");
        return;
        }
        }else if( !(tmpAdvCheckbox.value == null || tmpAdvCheckbox.value === "") ) {
        YTarg += "&" + tmpAdvCheckbox.value;
        }else{
        showDialog("發生錯誤!");
        hideMenu('', 'win');
        return;
        }
        }
        }
        //截掉開頭的"&"
        if (YTarg) {
        YTarg = YTarg.substr(1);
        YTarg = '?' +YTarg;
        } //iframe 參數 var YTwidth;
        var YTheight;
        var YTalign;
        //檢測width及height
        for(var i=0; i < $(ctrlid + '_menu_content').YTsize.length; i++){
        tmpSizeRadio =   $(ctrlid + '_menu_content').YTsize[i];
        if(tmpSizeRadio.checked){
        if(tmpSizeRadio.value=="custom"){
        if( !(/\D+/.test( $(ctrlid +'_width').value ) || /\D+/.test( $(ctrlid +'_height').value ))  ){
        if (funCheckNum($(ctrlid +'_width').value,true) && funCheckNum($(ctrlid +'_width').value,true) ){
        YTwidth=parseInt($(ctrlid +'_width').value,10);
        YTheight=parseInt($(ctrlid +'_height').value,10);
        break;
        }else{
        $(ctrlid + '_info_size').innerHTML='<b>請輸入有效尺寸!</b>';
        return; }
        }else{
        $(ctrlid + '_info_size').innerHTML='<b>請不要輸入非數字字元!</b>';
        return; }
        }else if (funCheckNum(tmpSizeRadio.value.split("x")[0],true) && funCheckNum(tmpSizeRadio.value.split("x")[1],true) ){
        YTwidth=parseInt(tmpSizeRadio.value.split("x")[0],10);
        YTheight=parseInt(tmpSizeRadio.value.split("x")[1],10);
        break;
        }else{
        showDialog("發生錯誤!");
        hideMenu('', 'win');
        return;
        }
        }
        }
        //檢測align
        for(var i=0; i < $(ctrlid + '_menu_content').align.length; i++){
        tmpAlignRadio = $(ctrlid + '_menu_content').align[i];
        if ( tmpAlignRadio.checked ) {
        if(  tmpAlignRadio.value=="left") {
        YTalign = "left"
        break;
        }else if(  tmpAlignRadio.value=="middle") {
        YTalign = "center"
        break;
        }else if(  tmpAlignRadio.value=="right") {
        YTalign = "right"
        break;
        }else{
        showDialog("發生錯誤!");
        return;
        }
        }
        }
        //組合出bbcode opentag='[YT=width='+YTwidth+' height='+YTheight+',align='+YTalign+']';
        closetag='[/YT]';
        var YTBBcodeText=opentag+YTid + YTarg+closetag;
        //插入字串
        insertText(YTBBcodeText,0,0,true,sel);
        hideMenu('', 'win');
        break;
        //----自訂義[YT]標籤編輯器選單---結束---------------------------------


        接著請把這些程式碼插進editor.js的最後一行:

        /*修改者:鐳鍶龍
        自訂義的輔助函數
        用途:輔助函數
        */
        function getYTid(url){
        var hostname;
        if(!(hostname=url.match(/^(?:http:\/\/|https:\/\/)?(www.youtube.com|youtu.be)\//))){
        return false;
        }
        switch(hostname[1]){
        case "www.youtube.com" :
        if( YTargs = url.match(/^(?:http:\/\/|https:\/\/)?www.youtube.com\/watch\?((?:[^&]+=[^&]*)(?:&[^&]+=[^&]*)*)/)[1] ){
        tmpYTid = YTargs.match(/v=([^&]+)/) ;
        tmpYTlist = YTargs.match(/list=([^&]+)/);
        return tmpYTid  ? ( tmpYTid[1] ? [ tmpYTid[1] , (tmpYTlist ? tmpYTlist[1] : false ) ]  : false ) : false ;
        }else{
        return false;
        }
        break;
        case "youtu.be" :
        tmpYTid = url.match(/^(?:http:\/\/|https:\/\/)?youtu.be\/([^\?]+)(?:\?((?:[^&]+=[^&]*)(?:&[^&]+=[^&]*)*))?/);
        YTargs = url.match(/^(?:http:\/\/|https:\/\/)?youtu.be\/([^\?]+)(?:\?((?:[^&]+=[^&]*)(?:&[^&]+=[^&]*)*))?/)[2] ? url.match(/^(?:http:\/\/|https:\/\/)?youtu.be\/([^\?]+)(?:\?((?:[^&]+=[^&]*)(?:&[^&]+=[^&]*)*))?/)[2] : "" ;
        tmpYTlist = YTargs.match(/list=([^&]+)/)  ; return tmpYTid ? ( tmpYTid[1] ? [ tmpYTid[1] , (tmpYTlist ? tmpYTlist[1] : false ) ]  : false ) : false ;
        break;
        default:
        return false;
        break;
        }
        return false;
        }
        //檢查是否為有效整數數字,是傳回true,如果是null,"",或包含其他符號則傳回false,chkZero為true時0列為無效數字
        function funCheckNum(chkNum,chkZero){
          if( /\D+/.test(chkNum) ){
          return false;
        }
        if(chkNum == null || chkNum === ""){
        return false;
        }
        if( !isUndefined(chkZero) && chkZero == true && parseInt(chkNum) === 0){
        return false;
        }
        return true;
        }
        function funSetInner( eID , etext ){
        $(eID).innerHTML = etext;
        }
        //設置收拉按鈕的圖形
        function funSetUpDown(eID){
        if(  $(eID).innerHTML == "▽"  ){
        $(eID).innerHTML = "△";
        }else{
        $(eID).innerHTML = "▽";
        }
        }
        function funSetHiseShow(eID){
        if($(eID).style.display == "none"){
        $(eID).style.display = "";
        }else{
        $(eID).style.display = "none";
        }
        }


        存檔收工,這樣子就可以直接貼入網址使用,編輯器會自動提出YouTubeID

        如此一來就不用在教使用者怎麼分辨YoutubeID了,很方便


        真是累死了,這大概算是龍第一個有用的作品XDD

        效果圖:
        部分參數可打開或是收起來




        本文章作者為:  LaysDragon鐳鍶龍
        轉貼請附上原文網址及作者。
        如果有其他用途希望引用,請留言並得到同意後再使用。