MediaWiki:Gadget-Certificate.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
const Certificate = {
init( $content ) {
const $templates = $content.find( '.template-get-certificate' );
$templates.each( Certificate.validate );
$templates.on( 'click', Certificate.generate );
},
validate() {
const data = this.dataset;
if ( !data.title ) {
this.classList.add( 'error' );
this.innerHTML = 'You need to specify the "title" parameter.';
return;
}
if ( !data.signature1 && !data.signature2 ) {
this.classList.add( 'error' );
this.innerHTML = 'You need to specify the "signature1" or "signature2" parameters (or both).';
return;
}
},
async generate() {
const data = this.dataset;
// Get the name and add it to the data
const name = prompt( 'What is your full name?' );
if ( !name ) {
return;
}
data.name = name;
// Build the HTML
const logos = document.createElement( 'div' );
logos.style.overflow = 'hidden';
logos.style.margin = '1rem';
if ( data.logo1 ) {
const logo1 = document.createElement( 'img' );
logo1.src = data.logo1;
logo1.style.float = 'left';
logo1.style.height = '50px';
logos.append( logo1 );
}
if ( data.logo2 ) {
const logo2 = document.createElement( 'img' );
logo2.src = data.logo2;
logo2.style.float = 'right';
logo2.style.height = '50px';
logos.append( logo2 );
}
const title = document.createElement( 'h1' );
title.textContent = data.title;
title.style.border = 'none';
title.style.margin = '1rem';
const subtitle = document.createElement( 'h2' );
subtitle.textContent = 'CERTIFICATE OF COMPLETION';
subtitle.style.border = 'none';
subtitle.style.margin = '1rem';
const text = document.createElement( 'p' );
text.style.margin = '1rem';
text.innerHTML = 'This is to certify that';
text.innerHTML += '<div style="margin: 1rem 0; font-size: 2rem;">' + data.name + '</div>';
text.innerHTML += 'has successfully completed the training';
if ( data.skill ) {
text.innerHTML += ' of ' + data.skill;
}
const date = new Date().toISOString().slice( 0, 10 );
text.innerHTML += ' on <div style="margin: 1rem 0; font-weight: bold;">' + date + '</div>';
const skills = document.createElement( 'div' );
skills.style.margin = '1rem';
if ( data.skills ) {
skills.innerHTML = '<div style="font-weight: bold;">Acquired skills:</div>';
skills.innerHTML += data.skills;
}
const signatures = document.createElement( 'div' );
signatures.style.margin = '1rem';
if ( data.signature1 ) {
const signature1 = document.createElement( 'div' );
signature1.innerHTML = data.signature1;
signature1.style.borderTop = '1px solid #a2a9b1';
signature1.style.paddingTop = '.5rem';
if ( data.signature2 ) {
signature1.style.float = 'left';
}
signatures.append( signature1 );
}
if ( data.signature2 ) {
const signature2 = document.createElement( 'div' );
signature2.innerHTML = data.signature2;
signature2.style.borderTop = '1px solid #a2a9b1';
signature2.style.paddingTop = '.5rem';
if ( data.signature1 ) {
signature2.style.float = 'right';
}
signatures.append( signature2 );
}
const certificate = document.createElement( 'div' );
certificate.style.border = '5px double #a2a9b1';
certificate.style.fontFamily = 'serif';
certificate.style.margin = '2rem';
certificate.style.padding = '1rem';
certificate.style.textAlign = 'center';
certificate.append( logos, title, subtitle, text, skills, signatures );
// Load dependencies
const promise1 = mw.loader.getScript( 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/3.0.3/jspdf.umd.min.js' );
const promise2 = mw.loader.getScript( 'https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.7/purify.min.js' );
const promise3 = mw.loader.getScript( 'https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js' );
await Promise.all( [ promise1, promise2, promise3 ] );
// Make the PDF
const doc = new jspdf.jsPDF( {
orientation: 'landscape'
} );
await doc.html( certificate, {
width: 297, // A4 pages measure 297mm x 210mm
windowWidth: 1000
} );
// Download the PDF
doc.save( 'certificate.pdf' );
}
};
mw.hook( 'wikipage.content' ).add( Certificate.init );