Site Builder
Editing:
tools-writing-blogssssssss.php
writable 0666
<?php /********************************************************************** * Promptinator – Blog‑Wizard (Aug‑2025 toolbar edition) **********************************************************************/ require_once $_SERVER['DOCUMENT_ROOT'].'/openai/init.php'; ai_handle_key_post(); // save / delete key first /* ---------- 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; } /* collect --------------------------------------------------- */ $topic = trim($_POST['topic']??''); $persona = trim($_POST['persona']??''); $aud = trim($_POST['aud']??''); $read = $_POST['level'] ?? 'General'; $kw = trim($_POST['keywords']??''); $url = trim($_POST['linkurl']??''); $sec = max(1,intval($_POST['sections']??3)); $par = max(1,intval($_POST['paras']??3)); $lang = $_POST['lang'] ?? 'English'; $style = $_POST['style'] ?? 'Creative'; $tone = $_POST['tone'] ?? 'Neutral'; $faq = isset($_POST['faq']); $cta = isset($_POST['cta']); $img = isset($_POST['images']); if ($topic===''){ echo json_encode(['error'=>'Topic required']); exit; } /* build prompt --------------------------------------------- */ $prompt = "As $persona, write a $lang blog post in a $tone tone and $style style about \"$topic\""; if ($aud) $prompt.=" for an audience of $aud"; $prompt .=". Structure it into $sec sections (start each with an <h2>) with $par paragraph" .($par>1?'s':'')." each. Keep the reading level around $read."; if ($kw) $prompt.=" Seamlessly weave in these keywords: $kw."; if ($kw && $url) $prompt.=" Hyperlink each keyword once to $url using <a>."; if ($faq) $prompt.=" After the main content add a 'FAQ' section (use <h2> FAQ)."; if ($cta) $prompt.=" End the post with a persuasive call‑to‑action paragraph."; if ($img) $prompt.=" Finally, suggest 3 royalty‑free hero‑image ideas (in plain text)."; $prompt.=" Finish with <p class=\"excerpt\">Excerpt: …</p>. Return ONLY HTML."; $html = ai_chat($prompt,['max_tokens'=>1600]); echo json_encode(['html'=>$html]); exit; } /* ---------- static 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}} #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{position:absolute;right:14px;top:50%;transform:translateY(-50%);background:none;border:none;font-size:1.3rem;cursor:pointer} </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"> <label>Topic <div style="position:relative"> <input id="topic" name="topic" placeholder="e.g. Sustainable boating" required> <button type="button" class="micBtn" id="mic">🎤</button> </div> </label> <div class="row"> <label>Persona / writing role <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> <div class="row"> <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> <div class="row"> <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> <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> <label>Include extras</label> <div class="row"> <label><input type="checkbox" name="faq" id="faq"> Add FAQ section</label> <label><input type="checkbox" name="cta" id="cta"> Add Call‑to‑Action</label> <label><input type="checkbox" name="images" id="images"> Suggest hero images</label> </div> <label>Prompt preview <textarea id="promptBox" readonly></textarea> </label> <button type="button" id="copyPrompt" class="btn copyBtn" hidden>Copy Prompt</button> <button class="btn" id="generate">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.4rem">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 ------------------------------------------- */ if ($('mic') && (window.SpeechRecognition||window.webkitSpeechRecognition)){ const SR = new (window.SpeechRecognition||window.webkitSpeechRecognition)(); SR.lang='en-US'; $('mic').onclick=()=>{try{SR.start();}catch{}}; SR.onresult=e=>{ $('topic').value=e.results[0][0].transcript; buildPrompt(); }; }else $('mic').style.display='none'; /* ----- prompt builder --------------------------------------- */ const keys=['topic','persona','aud','level','sections','paras','lang','style','tone', 'keywords','linkurl','faq','cta','images']; keys.forEach(k=>$(k)?.addEventListener('input',buildPrompt)); ['faq','cta','images'].forEach(id=>$(id).addEventListener('change',buildPrompt)); buildPrompt(); function buildPrompt(){ const t=$('topic').value.trim(); if(!t){$('promptBox').value='';$('promptField').value='';$('copyPrompt').hidden=true;return;} const persona=$('persona').value, aud=$('aud').value.trim(), lvl=$('level').value; const sec=$('sections').value, par=$('paras').value; const kw=$('keywords').value.trim(), url=$('linkurl').value.trim(); const lang=$('lang').value, style=$('style').value, tone=$('tone').value; const faq=$('faq').checked, cta=$('cta').checked, img=$('images').checked; let p = `As ${persona}, write a ${lang} blog post in a ${tone} tone and ${style} style about "${t}"`; if(aud) p+=` for an audience of ${aud}`; p+=`. Structure it into ${sec} sections (<h2>) with ${par} paragraph${par>1?'s':''} each. ` +`Keep reading level around ${lvl}.`; if(kw) p+=` Seamlessly weave in: ${kw}.`; if(kw&&url) p+=` Hyperlink each keyword once to ${url}.`; if(faq) p+=' Add an FAQ section.'; if(cta) p+=' End with a persuasive call‑to‑action.'; if(img) p+=' 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'))); /* ----- toolbar model sync ---------------------------------- */ const modelSel=document.querySelector('#modelSel'); if(modelSel) $('gen').querySelector('input[name=model]').value=modelSel.value; /* ----- AJAX ------------------------------------------------- */ $('gen').onsubmit=e=>{ e.preventDefault(); const go=$('generate');const spin=$('spin');const secs=$('secs'); go.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'); go.disabled=false; if(j.error){alert(j.error);return;} $('raw').value=j.html; $('rend').innerHTML=j.html; $('out').style.display=''; $('copyRaw').onclick=()=>navigator.clipboard.writeText($('raw').value).then(()=>flash($('copyRaw'))); $('copyRend').onclick=()=>navigator.clipboard.writeText($('rend').innerHTML).then(()=>flash($('copyRend'))); $('rend').scrollIntoView({behavior:'smooth'}); }) .catch(err=>{clearInterval(t);spin.classList.remove('show');go.disabled=false;alert(err);}); }; /* ----- copy helper ----------------------------------------- */ 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