គំរូ​ទំព័រ​ការផ្សាយ​ (post page) ផ្សំ​ឡើង​ដោយ​ផ្នែក​ផ្សេង​ៗ​ជា​ច្រើន មាន​ដូច​ជា​ផ្នែក​ចំណងជើង ផ្ទាំង​វាយ​អត្ថបទ ផ្នែក​ជ្រើស​រើសជំពូក ផ្នែក​រូបតំណាង ផ្នែក​កាលបរិច្ឆេទ និង​ ផ្នែក​បញ្ចូល​វីដេអូ​។ សំរាប់​ផ្នែក​វាយ​អត្ថបទ យើង​អាច​ប្រើប្រាស់​កម្មវិធី​​បើក​ចំហរ ckeditor ដែលអាច​ត្រូវ​ទាញយក​ពី​គេហទំព័រ https://ckeditor.com/ckeditor-5/download/ យក​មក​ទុក​នៅ​ក្នុង​ថត public/scripts/ckeditor ។ បន្ទាប់​មក​ទៀត យើង​ត្រូវ​បង្កើត​ឯកសារ config.js មួយ​និង​រក្សា​វា​ទុក​នៅ​ក្នុង​ថត public/scripts/ckeditor ។

 

var ckeditor

ClassicEditor
        .create( document.querySelector( '#editor' ), {
          
          toolbar: ['fontfamily', 'fontsize', 'fontcolor', 'bold', 'italic', 
          'bulletedList', 'indent', 'outdent', 'numberedList', 'link', 'blockQuote', 
          'insertTable','code', 'codeblock', 'imageinsert', 'mediaembed', 'undo', 'redo' ],
          fontFamily: {
            options: [
              'ឧត្តមាន​ជ័យ, OdorMeanChey', 'អក្សរដៃ, HandWriting',
              'គូលេន, Koulen', 'ក្រូច​ឆ្នារ, Limonf3',
              'បាយ័ន, Bayon', 'ក្រសាំង, Rooster',
              'មូល, Moul',​ 'Arial, Helvetica, sans-serif',
              'Courier New, Courier, monospace',
              'Georgia, serif',
              'Lucida Sans Unicode, Lucida Grande, sans-serif',
              'Tahoma, Geneva, sans-serif',
              'Times New Roman, Times, serif',
              'Trebuchet MS, Helvetica, sans-serif',
              'Verdana, Geneva, sans-serif',
            ],
            supportAllValues: true
          },
          
          fontSize: {
            options: [
                9,
                11,
                13,
                'default',
                17,
                19,
                21
            ],
            supportAllValues: true
          },
        })
        .then( editor => {
          ckeditor = editor
        })
        .catch( err => {
          console.error( err.stack )
        })

 

ការបង្កើត​ផ្ទាំង​វាយ​អត្ថបទ​ដែល​ជា​កម្មវិធី ckeditor ត្រូវ​ធ្វើ​ឡើង​ដោយ​បញ្ចូល​តំណរភ្ជាប់​ទៅ​កាន់​ឯកសារ ckeditor.js និង​ឯកសារ config.js ទៅ​ក្នុង​ឯកសារ Post.astro ។

 

<script is:inline src="/scripts/ckeditor/ckeditor.js"></script>

 

<script is:inline src="/scripts/ckeditor/config.js"></script>

 

ផ្នែក​និមួយ​ៗ​នៅ​ក្នុង​គំរូ​ទំព័រ​ការផ្សាយ ត្រូវ​​ភ្ជាប់​ទៅ​នឹងហេតុការណ៍ change ។ ដូចនេះ​នៅ​ពេល​ដែល​មាន​ការផ្លាស់ប្តូរ​នៅ​ក្នុង​ផ្នែក​ណា​មួយ ហេតុការណ៍ onbeforeunload នឹង​ត្រូវ​ភ្ជាប់​ទៅ​នឹង browser ដែល​នឹង​បណ្តាល​អោយ​មាន​ការប្រាប់​ដំណឹង​ស្តីពី​​​ការរក្សា​ទុក​នូវ​ទិន្នន័យ​មុន​នឹង​ដូរ​ឬ​បិទ​ទំព័រ​របស់​ browser ។

 

        $('.Post input').on('change', () => {
            window.onbeforeunload = save_data_check
        })
        
        ckeditor.model.document.on( 'change', () => {
            window.onbeforeunload = save_data_check
        } )

        $('.Post #form').on('submit', () => {
            window.onbeforeunload = null
            submitForm()
        })

        function save_data_check(){        
            return "Your changes may not be saved."
        }

        $('.Post #category').on('change', () => {
            const category = $('#category option:selected').text()
            $('select').prop('selectedIndex',0)
            let categories = $('[name=categories]').val()
            if(categories === ''){
                categories += category
            }else{
                categories += (`, ${category}`)
            }
    
            $('[name=categories]').val(categories)
            window.onbeforeunload = save_data_check
        })

        $('.Post #insert-video').on('click', () => {
            genJson()
        })

 

ចំពោះផ្នែក​បញ្ចូល​វីដេអូ យើង​ចាំបាច់​ត្រូវ​សរសេរ​​កូដ​ JavaScript មួយ​ចំនួន​ ក្នុង​ការបញ្ជូល​វីដេអូ​សំរាប់​ទិន្នន័យ​នៃ​ការផ្សាយ​។ ហើយ​វីដេអូ​ទាំងនោះ​ត្រូវ​កែ​អោយ​ទៅ​ជា​ប្រភេទ JSON មុន​នឹង​អាច​បញ្ជូល​វា​ទៅ​កាន់​មូលដ្ឋាន​ទិន្នន័យ MongoDB ។ យើង​អាច​សរសេរ​កូដ​ទាំងនោះ​នៅ​ក្នុង​ឯកសារ video.js និង​រក្សា​វា​ទុក​នៅ​ក្នុង​ថត public/scripts ​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​។

 

// public/scripts/video.js

let episode = 0

const genJson = () => {
    let json = $('input[name="videos"]').val()
    if((json !== '')&&(json !== '[]')){
        json = JSON.parse(json)
        episode = json.length
    }else{
        episode = 0
    }

    const type = $('select[name="type"').val()
    const id = $('input[name="videoid"').val()
    const status = $('select[name="status"').val()
            
    let video = {
        type: type,
        id: id,
        status: status,
    }
        
    let success = false
    
    for(let v in video){
        if(video[v] === ''){
            alert('You need to fill the required field '+v)
            success = false
            break
        }else{
            success = true
        }
    }

    if(success){
        let json = $('input[name="videos"]').val()
        video = {
            type: type,
            id: id,
            status: status,
        }
        if((json === '')){
            json = JSON.stringify([video])
            $('input[name="videos"]').val(json)
        }else{
            json = JSON.parse(json)
            json.push(video)
            json = JSON.stringify(json)
            $('input[name="videos"').val(json)
        }

        let html =``

        for(let v in video){
            html += `<input class="border px-2 py-1 border-slate-300 text-center" 
            value="${video[v]}" required />`
        }

        html += `<p title="លុប" onClick="deleteRow(event)"
        class="episode border px-2 py-1 border-slate-300 hover:opacity-75 text-center 
        bg-slate-200 hover:cursor-pointer">
        ${++episode}
        </p>`
        html = `<div class="grid md:grid-cols-[20%_auto_25%_15%] grid-cols-1">${html}</div>`
        
        $('.viddata div:eq(0)' ).after(html)
    }
}

function submitForm(){
    
    const is_video = $('input[name="videos"').val()

    if((is_video !== '') && (is_video !== '[]')){
        episode = JSON.parse(is_video).length
        let videos = []
        let part = {}
        let key = {0:'type', 1:'id', 2:'status'}

        for(let v=1; v<=episode; v++){
            for(let j=0; j<3; j++){
                part[key[j]] = $(`.viddata div:eq(${v}) input:eq(${j})`).val()
            }

            videos.push({...part})
        }

        const json = JSON.stringify(videos)
        $('input[name="videos"').val(json)
        alert(json)
    }
}

function deleteRow(e) {
    e.target.parentElement.remove()
    
    let index = parseInt(e.target.innerHTML)
    index = index - 1
    let json = $('input[name="videos"]').val()
    json = JSON.parse(json)
    json.splice(index, 1)
    episode = json.length
    json = JSON.stringify(json)
    $('input[name="videos"').val(json)

    for(let v=episode; v>-1; v--){
        $('.episode').eq(v).html(episode-v)
    }
}

 

យើង​អាច​​យក​កូដ​ខាង​លើ​នេះ​មក​ប្រើ​នៅ​ក្នុង​គំរូ​ទំព័រ​ការផ្សាយ តាម​រយៈ​តំណរភ្ជាប់៖

 

<script is:inline src="/scripts/video.js"></script>

 

ជា​រួម ​គំរួ​ទំព័រការផ្សាយ​មាន​​ទំរង់​ដូ​ច​ខាង​ក្រោម​នេះ​៖

 

<!--src/layouts/admin/Post.astro-->
---
---

<script is:inline src="/scripts/ckeditor/ckeditor.js"></script>

<section class="Post w-full">
    <form id="form" action="/api/post/create" method="post">
        <input class="border w-full px-2 py-1 border-slate-300"
            type="text" name="title" required placeholder="ចំណងជើង" 
        />
        <textarea class="" name="content" id="editor"></textarea>
        <input class="border w-full px-2 py-1 border-slate-300"
            type="text" name="categories" required placeholder="ជំពូក" 
        />
        <div class="grid md:grid-cols-[20%_auto_25%_15%] grid-cols-1"> 
            <select class="border px-2 py-1 border-slate-300" id="category">
                <option>ជ្រើសរើស​ជំពូក</option>
                <option>ព័ត៌មាន</option>
            </select>
            <input class="border px-2 py-1 border-slate-300"
                type="text" name="thumb" required placeholder="រូបតំណាង" 
            />
            <input class="border px-2 py-1 border-slate-300"
                type="datetime-local" step="1" name="datetime" required 
            />
            <input class="border border-slate-300 px-2 py-1 hover:opacity-75 bg-slate-200 hover:cursor-pointer"
                type="submit" value="ចុះ​ផ្សាយ" 
            />
            <input type="hidden" name="videos" value="" />
        </div>
    </form>

    <div class='grid md:grid-cols-[20%_auto_25%_15%] grid-cols-1'>
        <select name='type' class="border px-2 py-1 border-slate-300">
            <option>YouTube</option>
            <option>YouTubePlaylist</option>
            <option>Facebook</option>
            <option>OK</option>
            <option>Dailymotion</option>
            <option>Vimeo</option>
        </select>
        <input class="border px-2 py-1 border-slate-300"
            name='videoid' type='text' placeholder="អត្តសញ្ញាណ" required 
        />
        <select name='status' class="border px-2 py-1 border-slate-300">
            <option>ចប់</option>
            <option>នៅ​មាន​ត</option>
            <option>~ ចប់</option>
        </select>
        <input class="border border-slate-300 px-2 py-1 hover:opacity-75 bg-slate-200 hover:cursor-pointer"
            id='insert-video' type="button" value="បញ្ចូល​វីដេអូ" 
        />
    </div>

    <div class='viddata '>
        <div class="grid md:grid-cols-[20%_auto_25%_15%] grid-cols-1"></div>
    </div>

    <script>
        $('.Post input').on('change', () => {
            window.onbeforeunload = save_data_check
        })
        
        ckeditor.model.document.on( 'change', () => {
            window.onbeforeunload = save_data_check
        } )

        $('.Post #form').on('submit', () => {
            window.onbeforeunload = null
            submitForm()
        })

        function save_data_check(){        
            return "Your changes may not be saved."
        }

        $('.Post #category').on('change', () => {
            const category = $('#category option:selected').text()
            $('select').prop('selectedIndex',0)
            let categories = $('[name=categories]').val()
            if(categories === ''){
                categories += category
            }else{
                categories += (`, ${category}`)
            }
    
            $('[name=categories]').val(categories)
            window.onbeforeunload = save_data_check
        })

        $('.Post #insert-video').on('click', () => {
            genJson()
        })
    </script>
</section>

<script is:inline src="/scripts/ckeditor/config.js"></script>
<script is:inline src="/scripts/video.js"></script>
<style is:global>
    .ck-editor__editable {
        min-height: 250px;
    }
</style>

 

Netlify: https://khmerweb-dynamic-blog.netlify.app/admin

GitHub: https://github.com/Sokhavuth/dynamic-blog