Solace U — Content Generator

Solace U — Content Generator

Submit tips, videos, articles, and tutorials for the Solace U resource library. All submissions go through webmaster review.
Checking WordPress connection...
Review process: All submissions are sent to the webmaster for approval before going live on Solace U. You'll receive confirmation once your content is published.
Clear, specific, benefit-focused. Max 120 characters.
All Solace U content is automatically tagged under the "Solace U" parent category.
Auto-embeds at the top of the post.
Upload an image from your computer (JPG, PNG, GIF, WebP). Recommended: 1200×675px. Max size: 10MB.
Image preview will appear here
0 words (~0 min read)
\n\n' + (catName ? '

Category: ' + escapeHtml(catName) + '

\n' : '') + '

' + escapeHtml(v.title) + '

\n' + (v.videoUrl ? '

Video: ' + escapeHtml(v.videoUrl) + '

\n' : '') + (v.severity ? '

Severity: ' + escapeHtml(v.severity) + '

\n' : '') + body + '\n\n'; } function copyHtml() { var v = getValues(); var html = generateHtmlDoc(v); navigator.clipboard.writeText(html).then(function() { var btn = document.getElementById('btn-copy'); var orig = btn.textContent; btn.textContent = '✓ Copied!'; btn.classList.add('success'); setTimeout(function() { btn.textContent = orig; btn.classList.remove('success'); }, 2000); }); } function downloadHtml() { var v = getValues(); var slug = (v.title || 'solace-u-post').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, ''); var blob = new Blob([generateHtmlDoc(v)], { type: 'text/html' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = slug + '.html'; a.click(); URL.revokeObjectURL(url); } // ============================================================ // UTILITIES // ============================================================ function escapeHtml(str) { var div = document.createElement('div'); div.textContent = str || ''; return div.innerHTML; } function showToast(msg, type, duration) { var t = document.getElementById('toast'); t.className = 'toast ' + (type || ''); t.innerHTML = msg; setTimeout(function() { t.classList.add('show'); }, 10); setTimeout(function() { t.classList.remove('show'); }, duration || 3500); } function updateWordCount() { var text = document.getElementById('f-content').value; var words = text.split(/\s+/).filter(Boolean).length; var mins = Math.max(1, Math.round(words / 230)); document.getElementById('word-count').textContent = words.toLocaleString() + ' words (~' + mins + ' min read)'; } function updateImagePreview() { var fileInput = document.getElementById('f-image-file'); var wrap = document.getElementById('image-preview'); if (!fileInput || !fileInput.files || !fileInput.files[0]) { wrap.innerHTML = 'Image preview will appear here'; return; } var file = fileInput.files[0]; // Check size (warn if over 10MB) if (file.size > 10 * 1024 * 1024) { wrap.innerHTML = '⚠️ File too large (' + (file.size / 1024 / 1024).toFixed(1) + 'MB). Max 10MB.'; return; } var reader = new FileReader(); reader.onload = function(e) { wrap.innerHTML = 'Preview'; }; reader.readAsDataURL(file); } function toggleConditionalFields() { var type = document.getElementById('f-type').value; document.querySelectorAll('.conditional').forEach(function(field) { var showFor = field.dataset.showFor.split(','); field.classList.toggle('visible', showFor.indexOf(type) !== -1); }); } // ============================================================ // EVENT LISTENERS // ============================================================ document.getElementById('f-content').addEventListener('input', updateWordCount); document.getElementById('f-image-file').addEventListener('change', updateImagePreview); document.getElementById('f-type').addEventListener('change', toggleConditionalFields); // Keyboard shortcut: Ctrl/Cmd + Enter to publish document.addEventListener('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); publishToWP(); } }); // Init updateWordCount(); initConnection(); // When user comes back to this tab (e.g. after signing in on another tab), // immediately re-check auth for faster UX document.addEventListener('visibilitychange', function() { if (document.visibilityState === 'visible' && !wpNonce) { suCheckAuth(false); } }); window.addEventListener('focus', function() { if (!wpNonce) suCheckAuth(false); });