Siteβ―Builder
Editing:
demo.php
writable 0666
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Demo: Clickable Tokens & Live Conversion</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"> <style> body { max-width:800px; margin:2rem auto; font-family:system-ui,sans-serif; } h1, h2 { margin-top:2rem; } textarea { width:100%; height:4.5rem; font-family:monospace; margin-bottom:1rem; } .prompt-card { position:relative; background:#fff; border:1px solid #ddd; border-radius:8px; padding:1rem; margin-bottom:2rem; } .prompt-text { white-space:normal; line-height:1.5; } .token { display:inline-flex; margin:.2rem .1rem; padding:.3rem .6rem; background:#e8e0ff; color:#5c3bff; border-radius:4px; cursor:pointer; user-select:none; flex:0 1 auto; min-width:0; overflow-wrap:break-word; } .toolbar { position:absolute; background:#fff; border:1px solid #ccc; border-radius:6px; box-shadow:0 2px 12px rgba(0,0,0,.1); padding:.8rem; display:flex; flex-direction:column; gap:.6rem; z-index:10; width:260px; } .toolbar label { font-size:.9rem; font-weight:600; margin-bottom:.3rem; } .toolbar input[type="text"], .toolbar select, .toolbar textarea { width:100%; padding:.4rem; border:1px solid #999; border-radius:4px; font-size:1rem; } .ai-btns { display:flex; gap:.5rem; margin-top:1rem; } .ai-btns a { flex:1; text-align:center; padding:.6rem; border-radius:6px; color:#fff; text-decoration:none; font-weight:600; } .ai-btns a.chatgpt { background:#6c48ff; } .ai-btns a.perplexity { background:#1ca7ec; } .ai-btns a.copilot { background:#00c853; color:#173E22; } .ai-btns a:hover { filter:brightness(1.1); } </style> </head> <body> <h1>Demo: Clickable Tokens & Live Conversion</h1> <h2>Raw Prompt Template</h2> <textarea id="rawTpl" readonly> Generate a marketing headline for [C-service-] in [C-location-] that sounds [B-tone-|energetic|calm~energetic~] and mentions our commitment to [A-benefit-~spotless results~]. Then provide [D-count-5~5~] slug suggestions using the pattern [C-service-]-[C-location-], and select your plan: [D-package-|Basic Plan|Pro Plan|Enterprise Plan~Pro Plan~]. </textarea> <h2>Interactive Prompt</h2> <div id="app"></div> <script> (function(){ const tpl = document.getElementById('rawTpl').value.trim(); const RX = /\[(?:([ABCDI]?)-)?([^~|\-\]]+)(?:-([^~]*?))?(?:~([^~]*?)~)?\]/g; const SEP = ' β’ '; // Static options for service & location const SERVICE_OPTS = ['Roof Cleaning','Pressure Washing','Window Cleaning']; const LOCATION_OPTS = ['Seminole','Tampa','Orlando']; // Build meta + state const meta = [], state = {}; tpl.replace(RX,(m,cmd='',lab,ops='',def='')=>{ lab = lab.trim(); let opts = ops.split('|').filter(Boolean); // inject our static lists for C-service & C-location if (cmd==='C' && lab==='service') opts = SERVICE_OPTS; if (cmd==='C' && lab==='location') opts = LOCATION_OPTS; // initialize state if (cmd==='C') { state[lab] = def ? def.split(',').map(v=>v.trim()) : opts.slice(0,1); } else { state[lab] = def || opts[0] || ''; } meta.push({cmd:cmd||'A', lab, opts, rawOps:ops, defaultVal:def}); return ''; }); // Create prompt card const app = document.getElementById('app'); const card = document.createElement('div'); card.className = 'prompt-card'; card.innerHTML = ` <div class="prompt-text"></div> <div class="ai-btns"> <a class="chatgpt" data-base="https://chatgpt.com/?prompt=" target="_blank">ChatGPT</a> <a class="perplexity" data-base="https://www.perplexity.ai/search?q=" target="_blank">Perplexity</a> <a class="copilot" data-base="https://copilot.microsoft.com/?q=" target="_blank">Copilot</a> </div>`; app.append(card); // Floating toolbar const tb = document.createElement('div'); tb.className = 'toolbar'; tb.style.display = 'none'; card.append(tb); function renderText(){ const cont = card.querySelector('.prompt-text'); const html = tpl.replace(RX,(m,cmd='',lab)=>{ const idx = meta.findIndex(x=>x.lab===lab.trim()), val = state[lab.trim()]; if (cmd==='C') { return (Array.isArray(val)?val:[val]) .map(v=>`<span class="token" data-i="${idx}">${v}</span>`) .join(' '); } return `<span class="token" data-i="${idx}">${val}</span>`; }); cont.innerHTML = html.replace(/\n/g,' '); cont.querySelectorAll('.token') .forEach(t=>t.onclick = onTokenClick); } function rebuild(){ renderText(); const out = tpl.replace(RX,(m,cmd='',lab)=>{ const val = state[lab.trim()]; return cmd==='C' ? (Array.isArray(val)?val.join(SEP):val) : val; }); card.querySelectorAll('.ai-btns a').forEach(a=>{ a.href = a.dataset.base + encodeURIComponent(out); }); } function placeToolbar(tok){ const tr = tok.getBoundingClientRect(), cr = card.getBoundingClientRect(); tb.style.top = (tr.bottom - cr.top)+'px'; tb.style.left = (tr.left - cr.left)+'px'; } function onTokenClick(e){ const tok = e.currentTarget, idx = +tok.dataset.i, {cmd,lab,opts,rawOps,defaultVal} = meta[idx]; tb.innerHTML = ''; placeToolbar(tok); tb.style.display = 'flex'; // click-away close document.addEventListener('mousedown', function off(ev){ if (!tb.contains(ev.target) && ev.target!==tok){ tb.style.display='none'; document.removeEventListener('mousedown',off); } }); // label const lbl = document.createElement('label'); lbl.textContent = lab.replace(/_/g,' '); tb.append(lbl); // Multi-select checkboxes if (cmd==='C'){ const list = document.createElement('div'); list.className = 'checkbox-list'; opts.forEach(o=>{ const l = document.createElement('label'), cb = document.createElement('input'); cb.type = 'checkbox'; cb.value = o; cb.checked = (state[lab]||[]).includes(o); cb.onchange = ()=>{ state[lab] = [...list.querySelectorAll('input:checked')].map(i=>i.value); rebuild(); }; l.append(cb,' ',o); list.append(l); }); tb.append(list); } // Single-choice radio else if (cmd==='B'){ opts.forEach(o=>{ const l = document.createElement('label'), rd = document.createElement('input'); rd.type='radio'; rd.name=lab; rd.value=o; rd.checked = (state[lab]===o); rd.onchange = ()=>{ state[lab]=o; rebuild(); tb.style.display='none'; }; l.append(rd,' ',o); tb.append(l); }); } // Dropdown (numeric or text list) else if (cmd==='D'){ const sel = document.createElement('select'); if (rawOps.includes('|')){ // text-list dropdown opts.forEach(o=>{ const op=document.createElement('option'); op.value=op.textContent=o; if (o===state[lab]) op.selected=true; sel.append(op); }); } else if (/^[0-9]+$/.test(rawOps)){ // numeric dropdown 1β¦N const max = parseInt(rawOps,10)||0; for (let i=1; i<=max; i++){ const op=document.createElement('option'); op.value=op.textContent=String(i); if (String(i)===String(state[lab])) op.selected=true; sel.append(op); } } else { // fallback to any opts opts.forEach(o=>{ const op=document.createElement('option'); op.value=op.textContent=o; if (o===state[lab]) op.selected=true; sel.append(op); }); } sel.onchange = ()=>{ state[lab]=sel.value; rebuild(); tb.style.display='none'; }; tb.append(sel); } // Free-text area else { const ta = document.createElement('textarea'); ta.rows = 3; ta.value = state[lab]||''; ta.oninput = ()=>{ state[lab]=ta.value; rebuild(); }; tb.append(ta); } } // initial render renderText(); rebuild(); })(); </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel