Site Builder
Editing:
tools-writing-blogs-nice.php
writable 0666
<?php /********************************************************************** * Promptinator – Blog‑Wizard v2.0 (FAQs + Key‑Points, Aug‑2025) **********************************************************************/ require_once $_SERVER['DOCUMENT_ROOT'].'/openai/init.php'; ai_handle_key_post(); /* ---------- AJAX end‑point ------------------------------------ */ if ($_SERVER['REQUEST_METHOD']==='POST' && ($_GET['ajax']??'')==='1') { header('Content-Type: application/json; charset=utf-8'); if (!ai_has_key()) { echo json_encode(['error'=>'No API key']); exit; } $prompt = trim($_POST['prompt']??''); if(!$prompt) { echo json_encode(['error'=>'Prompt missing']); exit; } $html = ai_chat($prompt,['max_tokens'=>1600]); echo json_encode(['html'=>$html]); exit; } /* ---------- look‑up lists ------------------------------------- */ $langs=['English','Spanish','German','French','Italian','Portuguese','Dutch']; $styles=['Creative','Informative','Narrative','Persuasive','Analytical','Journalistic']; $tones =['Neutral','Cheerful','Humorous','Assertive','Inspirational','Professional','Emotional']; $personae=['Tech journalist','Seasoned sailor','Health coach','Finance analyst', 'Travel blogger','Food critic','Educator','Marketing strategist']; $levels=['Grade 6','Grade 8','Grade 10','Grade 12','Expert']; ?> <!doctype html> <html lang="en"><head> <meta charset="utf-8"> <title>Blog Wizard • Promptinator</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <style> :root{--bg:#f1f4fb;--card:#fff;--brand:#004cff;--brand-d:#0d5bfd;--shadow:0 6px 30px rgba(0,0,0,.08); --radius:26px;--red:#e24d4b;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif} *,*::before,*::after{box-sizing:border-box} body{margin:0;min-height:100vh;display:flex;flex-direction:column;background:var(--bg)} .breadcrumb{background:#eee;padding:.6rem 1rem;font-weight:600} .breadcrumb a{color:var(--brand);text-decoration:none} main{max-width:1000px;width:100%;margin:2.3rem auto;padding:0 1rem;flex:1} .tool{background:var(--card);box-shadow:var(--shadow);border-radius:var(--radius);padding:2rem;display:grid;gap:1.6rem} label{font-weight:600;font-size:.95rem;display:block;margin-bottom:.25rem} input,select,textarea{width:100%;padding:.75rem 1rem;border:1px solid #d0d6e7;border-radius:10px;font-size:1rem} textarea{min-height:90px;resize:vertical;font-family:ui-monospace,monospace} input:focus,select:focus,textarea:focus{outline:none;border-color:var(--brand)} .btn{background:var(--brand);color:#fff;border:none;border-radius:10px;padding:.9rem 1.7rem;font-size:1rem; font-weight:600;cursor:pointer} .btn:hover{background:var(--brand-d)} small{font-size:.8rem;color:#555} .row{display:grid;gap:1.2rem} @media(min-width:760px){.row{grid-template-columns:1fr 1fr}} @media(min-width:1020px){.row.wide{grid-template-columns:repeat(3,1fr)}} #spin{display:none;gap:.5ch;align-items:center;margin-top:.9rem} #spin.show{display:flex}#spin svg{width:20px;height:20px;animation:rot 1s linear infinite}@keyframes rot{to{transform:rotate(360deg)}} .preview{border:1px solid #d0d4e0;padding:1rem;border-radius:12px;background:#fafbff;max-height:60vh;overflow:auto} .micBtn,.delBtn{ position:absolute;top:50%;transform:translateY(-50%);border:none;background:none;font-size:1.35rem;cursor:pointer } .seed-wrap .micBtn{right:14px} .points-row{position:relative;width:100%;flex:0 0 100%} .points-row input{padding-right:5.3rem} .points-row .micBtn{right:48px} .points-row .delBtn{right:12px;color:var(--red)} </style> </head><body> <nav class="breadcrumb"> <a href="/members/dashboard.php">Dashboard</a> » <a href="/ai-tools/tools.php">AI Toolbox</a> » Blog Wizard <a href="/<?= htmlspecialchars($_SESSION['slug']??'') ?>/" style="float:right">View Site</a> </nav> <?php ai_render_key_bar(); ?> <main> <?php if(!ai_has_key()): ?> <div class="tool" style="text-align:center"> <h2>Connect your OpenAI key</h2> <p>Save the key in the black bar above to unlock the wizard.</p> </div> <?php else: ?> <div class="tool"> <h2>Create a high‑impact blog post</h2> <form id="gen" autocomplete="off"> <input type="hidden" name="model" value=""> <input type="hidden" name="prompt" id="promptField"> <!-- topic ------------------------------------------------ --> <label>Topic <div class="seed-wrap" style="position:relative"> <textarea id="topic" name="topic" rows="3" placeholder="e.g. Sustainable boating" required></textarea> <button type="button" class="micBtn" id="topicMic">🎤</button> </div> </label> <!-- persona / audience -----------------------------------> <div class="row"> <label>Persona <select id="persona" name="persona"><?php foreach($personae as $p) echo "<option>$p</option>"; ?></select> </label> <label>Target audience <small>(optional)</small> <input id="aud" name="aud" placeholder="e.g. first‑time boat buyers"> </label> </div> <!-- reading & structure ----------------------------------> <div class="row wide"> <label>Reading level <select id="level" name="level"><?php foreach($levels as $l) echo "<option>$l</option>"; ?></select> </label> <label># Sections <select id="sections" name="sections"><?php for($i=2;$i<=8;$i++) echo "<option>$i</option>"; ?></select> </label> <label># Paragraphs / section <select id="paras" name="paras"><?php for($i=1;$i<=6;$i++) echo "<option>$i</option>"; ?></select> </label> </div> <!-- language / style / tone ------------------------------> <div class="row wide"> <label>Language <select id="lang" name="lang"><?php foreach($langs as $l) echo "<option>$l</option>"; ?></select></label> <label>Style <select id="style" name="style"><?php foreach($styles as $s) echo "<option>$s</option>"; ?></select></label> <label>Tone <select id="tone" name="tone"><?php foreach($tones as $t) echo "<option>$t</option>"; ?></select></label> </div> <!-- keywords / URL ---------------------------------------> <div class="row"> <label>Keywords <input id="keywords" name="keywords" placeholder="solar boating, eco engines"> </label> <label>Link URL <input id="linkurl" name="linkurl" type="url" placeholder="https://example.com"> </label> </div> <!-- key points -------------------------------------------> <label>Important points (sections / arguments)</label> <div id="pointsWrap" style="display:flex;flex-direction:column;gap:.8rem"></div> <button type="button" id="addPoint" class="btn" style="width:150px">Add Point</button> <!-- FAQ / CTA / images -----------------------------------> <div class="row"> <label># FAQ questions <select id="faq" name="faq"> <?php for($i=0;$i<=10;$i++) echo "<option>$i</option>"; ?> </select> </label> <label><input type="checkbox" id="cta" name="cta"> Add Call‑to‑Action</label> <label><input type="checkbox" id="images" name="images"> Suggest hero images</label> </div> <!-- prompt preview ---------------------------------------> <label>Prompt preview <textarea id="promptBox" readonly></textarea> </label> <button type="button" id="copyPrompt" class="btn copyBtn" hidden>Copy Prompt</button> <!-- action -----------------------------------------------> <button id="generate" class="btn">Generate Blog Post</button> <div id="spin"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"/></svg><span id="secs">0</span> s</div> </form> <section id="out" style="display:none"> <h3>HTML source</h3> <textarea id="raw" readonly style="min-height:160px"></textarea> <button class="btn copyBtn" id="copyRaw">Copy HTML</button> <h3 style="margin-top:1.3rem">Rendered preview</h3> <div id="rend" class="preview"></div> <button class="btn copyBtn" id="copyRend">Copy Rendered</button> </section> </div> <?php endif; ?> </main> <script> (()=>{ const $=id=>document.getElementById(id); /* ---------- microphone for topic ---------------------------- */ if ($('topicMic') && (window.SpeechRecognition||window.webkitSpeechRecognition)){ const SR=new (window.SpeechRecognition||window.webkitSpeechRecognition)(); SR.lang='en-US'; $('topicMic').onclick=()=>{try{SR.start();}catch{}}; SR.onresult=e=>{$('topic').value=e.results[0][0].transcript;buildPrompt();}; }else $('topicMic').style.display='none'; /* ---------- dynamic points rows ----------------------------- */ function addPoint(val=''){ const row=document.createElement('div');row.className='points-row'; const inp=document.createElement('input'); inp.type='text';inp.name='points[]';inp.placeholder='Main point…';inp.value=val; const mic=document.createElement('button'); mic.type='button';mic.className='micBtn';mic.innerHTML='🎤'; const del=document.createElement('button'); del.type='button';del.className='delBtn';del.innerHTML='❌'; mic.onclick=()=>startRec(inp); del.onclick=()=>{row.remove();buildPrompt();}; row.append(inp,mic,del); $('pointsWrap').appendChild(row); } $('addPoint').onclick=()=>addPoint(''); addPoint(); // initial blank row /* ---------- shared SpeechRecognition ------------------------ */ function startRec(target){ const SR=window.SpeechRecognition||window.webkitSpeechRecognition; if(!SR){alert('Speech API unsupported');return;} const r=new SR();r.lang='en-US'; r.onresult=e=>{target.value=e.results[0][0].transcript;buildPrompt();}; try{r.start();}catch{} } /* ---------- build prompt preview ---------------------------- */ const inputs=['topic','persona','aud','level','sections','paras','lang','style','tone', 'keywords','linkurl','faq','cta','images']; inputs.forEach(id=>$(id)?.addEventListener('input',buildPrompt)); ['cta','images'].forEach(id=>$(id).addEventListener('change',buildPrompt)); document.addEventListener('input',e=>{if(e.target.name==='points[]')buildPrompt();}); buildPrompt(); function buildPrompt(){ const topic=$('topic').value.trim(); if(!topic){$('promptBox').value='';$('promptField').value='';$('copyPrompt').hidden=true;return;} const persona=$('persona').value, aud=$('aud').value.trim(), lvl=$('level').value, sec=$('sections').value, par=$('paras').value, kw=$('keywords').value.trim(), url=$('linkurl').value.trim(), lang=$('lang').value, style=$('style').value, tone=$('tone').value, faq=parseInt($('faq').value,10), cta=$('cta').checked, img=$('images').checked, pts=[...document.querySelectorAll('input[name="points[]"]')].map(i=>i.value.trim()).filter(Boolean); let p=`As ${persona}, write a ${lang} blog post in a ${tone} tone and ${style} style about "${topic}"`; if(aud) p+=` for an audience of ${aud}`; p+=`. Structure it into ${sec} section${sec>1?'s':''} (<h2>) with ${par} paragraph${par>1?'s':''} each. ` +`Keep reading level around ${lvl}.`; if(kw) p+=` Seamlessly weave in these keywords: ${kw}.`; if(kw&&url) p+=` Hyperlink each keyword once to ${url}.`; if(pts.length) p+=` Cover the following key points: ${pts.join('; ')}.`; if(faq) p+=` Add an FAQ section with exactly ${faq} questions and answers.`; if(cta) p+=' End with a persuasive call‑to‑action.'; if(img) p+=' Finally, suggest three royalty‑free hero image ideas.'; p+=' Finish with <p class="excerpt">Excerpt: …</p>. Return ONLY HTML.'; $('promptBox').value=p; $('promptField').value=p; $('copyPrompt').hidden=false; } $('copyPrompt').onclick=()=>navigator.clipboard.writeText($('promptBox').value).then(()=>flash($('copyPrompt'))); /* ---------- sync model from toolbar ------------------------- */ const ms=document.querySelector('#modelSel'); if(ms) $('gen').model.value=ms.value; /* ---------- AJAX submit ------------------------------------- */ $('gen').onsubmit=e=>{ e.preventDefault(); const btn=$('generate'),spin=$('spin'),secs=$('secs'); btn.disabled=true; spin.classList.add('show'); let s=0; secs.textContent='0'; const t=setInterval(()=>secs.textContent=++s,1000); fetch('?ajax=1',{method:'POST',body:new FormData($('gen'))}) .then(r=>r.json()) .then(j=>{ clearInterval(t); spin.classList.remove('show'); btn.disabled=false; if(j.error){alert(j.error);return;} $('raw').value=j.html; $('rend').innerHTML=j.html; $('out').style.display=''; $('rend').scrollIntoView({behavior:'smooth'}); }) .catch(err=>{ clearInterval(t); spin.classList.remove('show'); btn.disabled=false; alert(err); }); }; /* ---------- copy helpers ------------------------------------ */ $('copyRaw').onclick=()=>navigator.clipboard.writeText($('raw').value).then(()=>flash($('copyRaw'))); $('copyRend').onclick=()=>navigator.clipboard.writeText($('rend').innerHTML).then(()=>flash($('copyRend'))); function flash(btn){const t=btn.textContent;btn.textContent='✔ Copied';setTimeout(()=>btn.textContent=t,1200);} })(); </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel