Site Builder
Editing:
2.php
writable 0666
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Ultimate Prompt Playground v6 (Full)</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:900px; margin:2rem auto; font-family:system-ui,sans-serif; } h1 { text-align:center; margin-bottom:1.5rem; } .prompt-card { position:relative; background:#fff; border:1px solid #ddd; border-radius:8px; padding:1rem; margin-bottom:1.5rem; } .prompt-text { display:flex; flex-wrap:wrap; gap:.3rem; align-items:flex-start; line-height:1.6; white-space:normal; min-width:0; } .token { background:#e8e0ff; color:#5c3bff; padding:.3rem .6rem; border-radius:4px; cursor:pointer; user-select:none; flex:0 1 auto; min-width:0; overflow-wrap:break-word; word-break:break-word; } .token.placeholder { opacity:.6; } .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:300px; } .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; } .toolbar select { max-height:200px; overflow:auto; } .toolbar textarea { resize:vertical; } .checkbox-list { display:flex; flex-direction:column; gap:.4rem; max-height:200px; overflow:auto; padding-right:.2rem; } .checkbox-list label { display:flex; align-items:center; gap:.6rem; padding:.4rem .6rem; background:#f0f4ff; border-radius:4px; cursor:pointer; transition:background .2s; } .checkbox-list label:hover { background:#e0e8ff; } .checkbox-list input[type="checkbox"] { accent-color:#3b82f6; width:1.2em; height:1.2em; flex-shrink:0; } .ai-btns { display:flex; gap:.6rem; margin-top:1rem; } .ai-btns a { flex:1; text-align:center; padding:.7rem; 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>Ultimate Prompt Playground v6 (Full)</h1> <div id="app"></div> <script> (async()=>{ const SEP = ' • '; const RX = /\[(?:([ABCDI]?)-)?([^~|\-\]]+)(?:-([^~]*?))?(?:~([^~]*?)~)?\]/g; // Load business.json const params = new URLSearchParams(location.search); const ph = params.get('ph') || ''; let biz = {}; try { biz = await fetch(`/ph/${ph}/business.json`).then(r => r.json()); } catch {} // Load prompts.json let prompts = []; try { prompts = await fetch('prompts.json').then(r => r.json()).then(a => a.map(o => o.prompt)); } catch {} const app = document.getElementById('app'); function placeToolbar(tb, tok) { const card = tok.closest('.prompt-card'); const tr = tok.getBoundingClientRect(), cr = card.getBoundingClientRect(); tb.style.top = (tr.bottom - cr.top) + 'px'; tb.style.left = (tr.left - cr.left) + 'px'; } for (const tpl of prompts) { const meta = [], state = {}; // Initialize state from biz data ['name','slogan','description','address','city','state','zip','phone','website'] .forEach(k => state[k] = biz[k] || ''); state.service = biz.tags || []; state.location = biz.location_tags || []; // Build metadata and initial token state tpl.replace(RX, (m, cmd='', lab, ops='', def='') => { lab = lab.trim(); let opts = []; if (cmd === 'C') { // Multi-select: dynamic service/location or provided opts if (lab === 'service') opts = [...state.service]; else if (lab === 'location') opts = [...state.location]; else opts = ops.split('|').filter(Boolean); state[lab] = def ? def.split(',').map(v => v.trim()) : (opts.length ? [opts[0]] : []); } else if (cmd === 'B') { // Single-choice opts = ops.split('|').filter(Boolean); state[lab] = def || opts[0] || ''; } else if (cmd === 'D') { // Dropdown: if list provided, use opts; numeric otherwise if (ops.includes('|')) { opts = ops.split('|').filter(Boolean); state[lab] = def || opts[0] || ''; } else { opts = []; state[lab] = def || state[lab] || ''; } } else if (cmd === 'I') { // I-token: stores URLs or fallback opts = ops.split('|').filter(Boolean); state[lab] = def || state[lab] || ''; } else { // A-token state[lab] = def || state[lab] || ''; } meta.push({ cmd: cmd || 'A', lab, opts, rawOps: ops, defaultVal: def }); return ''; }); // Render prompt tokens const html = tpl.replace(RX, (m, cmd='', lab) => { const label = lab.trim(); const idx = meta.findIndex(x => x.lab === label); const v = state[label]; if (cmd === 'C') return (v || []).map(x => `<span class="token" data-i="${idx}">${x}</span>` ).join(' '); return `<span class="token" data-i="${idx}">${v || ''}</span>`; }).replace(/\n/g,'<br>'); const card = document.createElement('div'); card.className = 'prompt-card'; card.innerHTML = ` <div class="prompt-text">${html}</div> <div class="ai-btns"> <a class="chatgpt" data-base="https://chatgpt.com/?prompt=">ChatGPT</a> <a class="perplexity" data-base="https://www.perplexity.ai/search?q=">Perplexity</a> <a class="copilot" data-base="https://copilot.microsoft.com/?q=">Copilot</a> </div>`; app.append(card); const tb = document.createElement('div'); tb.className = 'toolbar'; tb.style.display = 'none'; card.append(tb); function rebuild() { const out = tpl.replace(RX, (m, cmd='', lab) => { const val = state[lab.trim()]; return cmd === 'C' ? (val || []).join(SEP) : val || ''; }); card.querySelectorAll('.ai-btns a').forEach(a => a.href = a.dataset.base + encodeURIComponent(out) ); } rebuild(); // Click handler for tokens card.addEventListener('click', e => { const tok = e.target.closest('.token'); if (!tok) return; const idx = +tok.dataset.i; const { cmd, lab, opts, rawOps, defaultVal } = meta[idx]; tb.innerHTML = ''; placeToolbar(tb, tok); tb.style.display = 'flex'; const onDocClick = ev => { if (!tb.contains(ev.target) && ev.target !== tok) { tb.style.display = 'none'; document.removeEventListener('mousedown', onDocClick); } }; document.addEventListener('mousedown', onDocClick); const labelEl = document.createElement('label'); labelEl.textContent = lab.replace(/_/g,' '); tb.append(labelEl); if (cmd === 'C') { const list = document.createElement('div'); list.className = 'checkbox-list'; opts.forEach(o => { const lb = document.createElement('label'); const 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); tok.textContent = state[lab].join(', '); rebuild(); }; lb.append(cb, ' ', o); list.append(lb); }); tb.append(list); } else if (cmd === 'B') { opts.forEach(o => { const lb = document.createElement('label'); const rd = document.createElement('input'); rd.type = 'radio'; rd.name = lab; rd.value = o; rd.checked = (state[lab] === o); rd.onchange = () => { state[lab] = o; tok.textContent = o; rebuild(); tb.style.display='none'; }; lb.append(rd, ' ', o); tb.append(lb); }); } else if (cmd === 'D') { const sel = document.createElement('select'); if (opts.length) { opts.forEach(o => { const op = document.createElement('option'); op.value = o; op.textContent = o; if (o === state[lab]) op.selected = true; sel.append(op); }); } else if (/^\d+$/.test(rawOps || defaultVal)) { const max = parseInt(rawOps || defaultVal,10) || 0; for (let i=1; i<=max; i++) { const op = document.createElement('option'); op.value = String(i); op.textContent = String(i); if (String(i) === state[lab]) op.selected = true; sel.append(op); } } sel.onchange = () => { state[lab]=sel.value; tok.textContent=sel.value; rebuild(); tb.style.display='none'; }; tb.append(sel); } else if (cmd === 'I') { if (opts.length) { const select = document.createElement('select'); const placeholder = document.createElement('option'); placeholder.disabled = true; placeholder.selected = true; placeholder.textContent = state[lab] || 'Select...'; select.append(placeholder); opts.forEach(url => { const op = document.createElement('option'); op.value = url; op.textContent = url; select.append(op); }); const iframe = document.createElement('iframe'); iframe.hidden = true; iframe.style.width='100%'; iframe.style.height='200px'; const btn = document.createElement('button'); btn.textContent='Use site'; btn.style.marginTop='.6rem'; select.onchange = () => { iframe.hidden=false; iframe.src=select.value; }; btn.onclick = () => { state[lab]=select.value; tok.textContent=select.value; rebuild(); tb.style.display='none'; }; tb.append(select, iframe, btn); } else { const inp = document.createElement('input'); inp.type='number'; inp.value=state[lab]||''; inp.oninput = () => { state[lab]=inp.value; tok.textContent=inp.value; rebuild(); }; tb.append(inp); } } else if (cmd === 'A') { const ta = document.createElement('textarea'); ta.rows=4; ta.value=state[lab]; ta.oninput = () => { state[lab]=ta.value; tok.textContent=ta.value; rebuild(); }; tb.append(ta); } else { const inp = document.createElement('input'); inp.type='text'; inp.value=state[lab]||''; inp.oninput = () => { state[lab]=inp.value; tok.textContent=inp.value; rebuild(); }; tb.append(inp); } }); } })(); </script> <!-- Tutorial Section for Shortcodes --> <section style="margin-top:2rem;padding:1rem;border-top:1px solid #ddd;"> <h2>Shortcode Tutorial</h2> <p>This section explains how to format each shortcode so it works with the playground script:</p> <ul> <li><strong>A‑tokens (Free Text)</strong>:<br> Format: <code>[A-key-~default~]</code><br> Example: <code>[A-title-~Homepage~]</code> renders a textarea defaulting to "Homepage".</li> <li><strong>B‑tokens (Single Choice)</strong>:<br> Format: <code>[B-key-|opt1|opt2|opt3|~default~]</code><br> Example: <code>[B-tone-|friendly|urgent|professional|~friendly~]</code> renders radio buttons, defaulting to "friendly".</li> <li><strong>C‑tokens (Multi‑Select)</strong>:<br> Format: <code>[C-key-|opt1|opt2|opt3|]</code> or dynamic tags <code>[C-service-]</code>, <code>[C-location-]</code><br> Example: <code>[C-extra-|a|b|c]</code> renders styled checkboxes, selecting the first by default.</li> <li><strong>D‑tokens (Dropdown)</strong>:<br> - Numeric: <code>[D-count-5~3~]</code> renders a 1…5 dropdown, defaulting to 3.<br> - List: <code>[D-list-|a|b|c|~b~]</code> renders a text dropdown defaulting to "b".</li> <li><strong>I‑tokens (Iframe Preview)</strong>:<br> Format: <code>[I-key-|url1|url2|…]</code><br> Example: <code>[I-reference-|https://…|https://…]</code> renders a URL select, inline iframe preview, and Use site button.</li> </ul> </section> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel