') + ')', 'gi');
if (regex.test(text)) {
found = true;
var frag = document.createDocumentFragment();
var parts = text.split(regex);
parts.forEach(function(part, i) {
if (i % 2 === 0) {
frag.appendChild(document.createTextNode(part));
} else {
var span = document.createElement('span');
span.className = 'userscript-highlight';
span.textContent = part;
frag.appendChild(span);
}
});
node.parentNode.replaceChild(frag, node);
}
});
} else if (node.nodeType === 1 && node.childNodes) { // element
var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];
if (!skipTags.includes(node.tagName)) {
Array.from(node.childNodes).forEach(highlight);
}
}
}
highlight(document.body);
// Re-highlight on dynamic content
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(m) {
m.addedNodes.forEach(function(node) {
if (node.nodeType === 1 || node.nodeType === 3) highlight(node);
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); }
})();
(function(){
try {
var __m = "*";
var __re = new RegExp('^' + ".*" + ', 'i');
if (__m === '*' || __re.test(location.href)) {
// Strip utm_, fbclid, gclid, etc. from all links on page
(function() {
var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',
'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',
'ref', 'ref_src', 'source', 'medium', 'campaign'];
function cleanUrl(url) {
try {
var u = new URL(url, window.location.origin);
var changed = false;
trackingParams.forEach(function(p) {
if (u.searchParams.has(p)) {
u.searchParams.delete(p);
changed = true;
}
});
return changed ? u.toString() : url;
} catch (e) {
return url;
}
}
function cleanLinks() {
document.querySelectorAll('a[href]').forEach(function(a) {
var clean = cleanUrl(a.href);
if (clean !== a.href) a.href = clean;
});
}
cleanLinks();
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(m) {
m.addedNodes.forEach(function(node) {
if (node.nodeType === 1) {
if (node.tagName === 'A') cleanLinks();
node.querySelectorAll('a[href]').forEach(function(a) {
var clean = cleanUrl(a.href);
if (clean !== a.href) a.href = clean;
});
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); }
})();
(function(){
try {
var __m = "youtube.com";
var __re = new RegExp('^' + "youtube\\.com" + ', 'i');
if (__m === '*' || __re.test(location.href)) {
// Auto-enable theater mode on YouTube
(function() {
function tryTheater() {
var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]');
if (btn && !btn.classList.contains('activated')) {
btn.click();
}
}
// Try immediately
tryTheater();
// Try after navigation (SPA)
var lastUrl = location.href;
setInterval(function() {
if (location.href !== lastUrl) {
lastUrl = location.href;
setTimeout(tryTheater, 500);
}
}, 1000);
// Also try on player load
var observer = new MutationObserver(tryTheater);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); }
})();
(function(){
try {
var __m = "*";
var __re = new RegExp('^' + ".*" + ', 'i');
if (__m === '*' || __re.test(location.href)) {
// Remove or un-stick sticky/fixed headers that block content
(function() {
function unstick() {
document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) {
if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {
el.style.position = 'static';
el.style.top = 'auto';
el.style.zIndex = 'auto';
}
});
}
unstick();
var observer = new MutationObserver(unstick);
observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });
})();
}
} catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); }
})();
})();
GitHub - wolffe/fx-forms: A small contact-form plugin for ClassicPress. Build forms in the admin, drop them anywhere with a shortcode, and get notified by email. · GitHub
You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
=== FX Forms ===
Contributors: butterflymedia
Tags: forms, contact form, classicpress
Requires at least: 5.3
Tested up to: 6.8
Requires PHP: 8.1
Stable tag: 2.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
A small contact-form plugin for ClassicPress. Build forms in the admin, drop them anywhere with a shortcode, and get notified by email.
== Description ==
FX Forms is a minimal, no-frills form plugin built for ClassicPress (works on WordPress too). It does one thing well: lets you define forms in the admin and embed them in pages or posts. When a visitor submits, you get an email — no submissions are stored in the database.
* Custom post type "Forms" for managing form definitions
* Field types: text, full name, email, phone, number, URL, date, time, textarea, select, checkbox
* Full / half width fields, side-by-side via CSS Grid
* Per-field help text shown under each input
* Drag-and-drop field ordering (uses ClassicPress 2.7+ native SortableJS)
* Generic fields — pick any type and give it your own label
* Embed with `[fxform id=N]` shortcode
* Sends email on submit, supports multiple recipients (comma- or semicolon-separated)
* Sets `Reply-To` automatically when an email field is present
* Honeypot anti-spam field built in
* No submissions stored in the database
* No jQuery, no React, no build step — vanilla JS only
== Installation ==
1. Upload the plugin folder to `/wp-content/plugins/`.
2. Activate it in the Plugins menu.
3. Go to **FX Forms → Add New** and build your form.
4. Copy the shortcode shown above the title and paste it into any page or post.
== Frequently Asked Questions ==
= How do I embed a form? =
Each form has a shortcode shown at the top of the editor — `[fxform id=42]`. Paste it into any page or post.
= Where do submissions go? =
Straight to your email. Nothing is stored on the site.
= Can I send to multiple recipients? =
Yes — in the form's "Send to" field, separate addresses with commas or semicolons.
= Can replies go to the visitor? =
If your form has a field of type "Email" and the visitor fills it in, that address is automatically set as the `Reply-To` header on the notification email.
= What email placeholders are available? =
`{form_title}`, `{form_id}`, `{data}` (all fields), and any individual field id like `{email}` or `{message}`. For "Full Name" fields, `{your_name}` produces "First Last", and `{your_name_first}` / `{your_name_last}` work too.
== Changelog ==
= 2.1.0 =
* New: Global Settings page (FX Forms → Settings) — choose the sending method and configure the email log.
* New: SMTP2Go mailer — enter your API key and select SMTP2Go as the mailer to send via the SMTP2Go REST API instead of wp_mail. More mailer options can be added later.
* New: Email log — optionally store a copy of every sent email in a dedicated database table; configurable maximum entry count (default 1000); entries are pruned automatically; viewable and clearable from FX Forms → Email Log.
* New: Per-form CAPTCHA — enable a text verification code on any form to deter spam; stateless (no PHP sessions), challenge stored in a short-lived transient.
= 2.0.0 =
* Initial release as FX Forms.
* Procedural PHP 8.1+, vanilla JS, no jQuery, no React, no build step.
* Generic field builder: pick a type, give it your label.
* Field types include a composite "Full Name" (First / Last sub-inputs).
* Full / half width fields via CSS Grid.
* Per-field help text shown under each input.
* No submissions are stored — emailed only.
* Server-rendered shortcode, classic POST/redirect submit flow (no REST).
* Multiple notification recipients.
* Automatic Reply-To from a submitted email field.
* Built-in honeypot.
About
A small contact-form plugin for ClassicPress. Build forms in the admin, drop them anywhere with a shortcode, and get notified by email.