-
Posts
653 -
Joined
-
Last visited
-
Days Won
7
rick last won the day on March 26
rick had the most liked content!
Contact Methods
-
Website URL
https://simulatedconcepts.com
Profile Information
-
Gender
Male
-
Location
Texas
-
Interests
Web applications, scotch, hunting, fishing, scotch, graphic design. Did I mention scotch?
Recent Profile Visitors
8,795 profile views
rick's Achievements
-
Thanks @szabesz My comparison would be based strictly on licensing and 3rd party dependencies, so it wouldn't be fair. I didn't want to inject any processwire modules/jquery, etc. into the frontend. I leave processwire to do what it does best. I found sundeditor while working on a forum project a few years back. The source css/js files are fairly easy to update/customize, and the plain javascript, MIT license, and source were big selling points. So I can't really offer a comparison as I haven't tried modifying tinymce/ckeditor.
-
Cre8aplace -- ProcessWire Showcase Overview Cre8aplace is a full-featured social networking platform built entirely on ProcessWire 3.0.255, PHP 8.4, and plain JavaScript/HTML/CSS. No frontend frameworks, no build tools, no bundlers. It delivers the core experience people expect from a social platform -- profiles, messaging, groups, newsfeeds, marketplace, blogs -- while prioritizing user privacy and data control. The site is currently in soft launch at [cre8aplace.com](https://cre8aplace.com). I started this project over five years ago and was recently revived with the availability of time (I'm retired). The goal was to build a platform where users own their experience -- where no data is sold, no algorithms manipulate what you see, and the platform exists to serve its members rather than advertisers. I've used ProcessWire for many years on various projects so it was the natural foundation. Ryan's philosophy of minimal opinions and maximum flexibility aligned perfectly with my project that needed to bend a CMS into something it wasn't explicitly designed for -- a real-time social networking platform. Where other CMSs would have fought at every turn with rigid content models and opinionated routing, ProcessWire simply got out of the way. A major thank you to Ryan! What ProcessWire Solved User Management Without a Separate Database ProcessWire's user system eliminated the need for a standalone user table entirely. Each member account carries approximately 50 custom fields -- everything from profile settings and privacy controls to notification preferences and subscription status. PW's field system handles all of this natively, with no separate profile table, no ORM, and no migration headaches when fields change. The Entity Page Tree Every entity type on the platform -- Groups, Pages (business presence), Events, Markets, Blogs, Movies, Games -- lives as a ProcessWire page with its own template. The page tree gives a natural hierarchy: /groups/ /groups/hiking-enthusiasts/ /groups/local-music/ /pages/ /pages/joes-coffee/ /markets/ /markets/handmade-goods/ Each entity type gets its own template file, its own toolbar configuration, and its own permission rules, but they all share the same rendering components (page header, toolbar, left aside, right aside). ProcessWire's template system made this architecture effortless. Flexible Templating as a Router I used ProcessWire's template system not as a traditional page renderer, but as a thin router/dispatcher. A single 'profile.php' template handles 12 different operations (timeline, account settings, privacy, messages, friends, membership, etc.) by dispatching to focused include files. Each include contains paired display and process functions. PW's template prepend (_init.php) bootstraps every request with shared utilities, configuration, and security setup. Admin Backend for Free ProcessWire's admin interface provided a complete backend without building one. SVG icons are stored as PW pages (37 icons, each with SVG markup in a textarea field). Site-wide configuration lives in a JSON field on a settings page, accessible from both PHP and JavaScript. Reaction types, emoji sets, and content categories are all managed through PW's admin. Authentication Built on Solid Ground Rather than building authentication from scratch, I extended ProcessWire's session and user system with custom email verification, token-based password reset, persistent remember-me login, and bot prevention. PW handles the password hashing, session management, and role assignment while I built the user-facing flows on top. Role Hierarchy The platform's permission system maps directly to ProcessWire roles: member < moderator < owner < administrator < superuser PW's role checking ($user->hasRole(), $user->isSuperuser()) powers everything from toolbar visibility to AJAX endpoint authorization. Group moderators and page employees add entity-scoped permissions on top of the global role hierarchy. Custom ProcessWire Modules I built four custom modules over the years while working on various other projects that extend ProcessWire's capabilities: - ViridiaCaptcha -- Bot prevention for registration and authentication forms. Integrates directly with PW's form processing. - ViridiaCalendar -- A full event calendar with RSVP tracking, recurring events, ICS, and profile-level event management. Renders calendar views and manages event CRUD through ProcessWire's module API. - ViridiaTicketing -- Support ticket system for user-to-admin communication. Built as a PW module with its own database tables and admin interface. - ViridiaGovFeed -- An automated government legislative feed that fetches federal bills from Congress.gov, executive orders and rules from the Federal Register, and state-level legislation via the LegiScan API. It publishes curated topics to a system-owned Page entity. Users follow the page to see legislative headlines in their newsfeed. Runs on a 6-hour cron cycle with deduplication and fetch logging. Architecture Highlights Hybrid Data Model I use ProcessWire pages for entities and users, but custom MariaDB tables for high-volume relational data. I created over 20 custom tables to handle topics, comments, replies, messages, relationships, reactions, notifications, marketplace orders, product variants, reviews, and more. This hybrid approach gives me the best of both worlds -- PW's flexible page management for entities, and direct SQL performance for data that sees thousands of writes per day. Encrypted Control Parameters What I am most proud of is no database ID ever appears in a URL, query string, or HTML attribute on this platform. Every sensitive identifier is encrypted with AES-256-CBC using ProcessWire's private key, passed as an opaque 'data-param' attribute, and decrypted server-side before processing. JavaScript never sees a real ID -- it just passes encrypted blobs back to the server. This is the backbone of the platform's privacy guarantees. AJAX-Driven Interface The platform runs over 50 AJAX actions across 8 endpoint routers. Every interactive operation -- posting a topic, sending a message, toggling a reaction, managing a marketplace order -- happens through AJAX calls that return JSON with server-rendered HTML. No client-side templating, no virtual DOM, no state management library. The server renders the HTML, the client inserts it. Single CSS File, No Framework The entire platform's styling lives in a single 132KB CSS file. Layout uses CSS Grid (3-column desktop, single-column mobile). Theming uses OKLch color space with CSS custom properties -- users pick an accent color via a color picker, and the entire UI adapts through computed color relationships. No Bootstrap, no Tailwind, no preprocessor. No Build Pipeline I wrote 23 JavaScript files as plain ES6+ and served directly. For production, a PHP-based minifier (matthiasmullie/minify) compresses them, and a GUID generator creates randomized filenames for cache busting. The entire "build" process is three shell commands. No webpack, no Vite, no npm. External Dependencies The platform uses only three external dependencies: 1. SunEditor (MIT license) -- WYSIWYG editor for blog posts. The only client-side library on the platform. Everything else is hand-written JavaScript. 2. Stripe PHP SDK -- Powers three subscription tiers (Free at $0, Standard at $8.95/month, Extended at $16.95/month) and marketplace seller payouts via Stripe Connect Express. The SDK is vendored directly in the project -- no Composer. 3. Wasabi S3 -- Cloud object storage for album images and marketplace product photos. Accessed via direct S3 API calls from PHP. Everything else -- UI components, animations, form handlers, real-time polling system -- is custom PHP, JavaScript, HTML, and CSS. Platform Features Social Core - User profiles with visitor viewing via opaque GUID URLs, granular privacy controls, and friend relationships with request/accept/block workflows - Newsfeed aggregating activity from friends, followed groups, pages, and markets - Topic creation with multi-image upload (adaptive grid layout, each with caption and tags), comments, replies, reactions, emoji picker, @mentions, link previews, and topic sharing - Real-time messaging supporting direct messages, multi-user conferences, group chat, page staff chat, system announcements, and moderation incident channels - Notification system with smart aggregation (groups repeat members until read), role-based filtering, and infinite scroll - Carousel view of multiple images with editing Community Entities - Groups with public/private/secret visibility, moderator roles, member approval, post approval queue, rules display, and ownership transfer - Pages (business presence) with follower system, employee roles, and staff-only chat channels Premium Features (Subscription-Gated) - Marketplace with Stripe Connect seller onboarding, product variants, shopping cart, checkout, digital downloads via pre-signed S3 URLs, order management, revenue reports, verified-purchase reviews, wishlists, and market following with new-product notifications - Blogs with SunEditor WYSIWYG, full CRUD, and newsfeed integration - Movies and Games as browseable entertainment entity types - Events powered by the ViridiaCalendar module with RSVP tracking - Schedule future topic postings - State-level government legislation tracking (3-state limit on Standard, unlimited on Extended) Administration - Admin panel with a reusable data table module -- a config-driven system where new admin tables require only a configuration array. Six tables migrated: Users, Groups, Pages, Categories, Reactions, Reports - Content moderation with report handling, per-report discussion channels, and moderator action tracking - Government legislative feed management with force-fetch and status monitoring By the Numbers | Metric | Value | | ------------------------- | ---------------------- | | Custom database tables | 20+ | | SQL migration files | 46 | | Custom user fields | ~50 | | JavaScript files | 23 (~500KB source) | | CSS | 1 file (132KB) | | PHP include files | 50+ | | Custom PW modules | 4 | | Utility functions library | 113KB (_functions.php) | | AJAX actions | 50+ | | npm dependencies | 0 | | Composer dependencies | 0 | | Build steps | 0 | Technology Stack - CMS: ProcessWire 3.0.255 - Language: PHP 8.4 - Database: MariaDB 15.0+ on Debian 12 - Server: Apache 2.4 - Frontend: Plain JavaScript (ES6+), HTML5, CSS3 - Payments: Stripe (subscriptions + Connect marketplace payouts) - Storage: Wasabi S3 (images) - Editor: SunEditor (blog WYSIWYG) - Frameworks: None - Build tools: None
- 2 replies
-
- 12
-
-
I am creating a module. The first-time install works without error, and the module functions without error. However, when I uninstall the module, then attempt to install the module again, I get the following error: "Unable to install module [module]: Role collision detected ([role]): role already exists." The role was deleted successfully, and no reference to that name exists in the database. Has anyone come across this before?
-
I appreciate that Jan. Works like a charm.
-
Two things first: 1) My searches returned no results for this issue. 2) I don't use github so I do not know how to submit a possible issue. So I would like to ask the community if I have either made a mistake (which is most likely) or have an actual issue; In which case I hope one of you more familiar with github can submit this as an issue. I've create a user profile page whereby the user can upload an avatar image. It works to the point of actually saving the image file in the correct location with the correct filename, but does not assign that to the image field due to the issues noted later. This is the code: ... $upload_path = wire()->config->paths->assets . "files/avatar_uploads/"; if(!is_dir($upload_path)) { if(!wireMkdir($upload_path)) throw new WireException("No upload path!"); } try { $user->first_name = $first_name; $user->last_name = $last_name; $user->user_bio = $user_bio; $user->share_bio = $share_bio; $files = new WireUpload('avatar'); $files->setDestinationPath($upload_path); $files->setTargetFilename($user->name."-avatar"); $files->setValidExtensions(['jpg','jpeg','png']); $files->setOverwrite(true); $file = $files->execute(); //returns array of uploaded filenames if($files->getErrors()){ foreach($file as $filename) @unlink($upload_path.$filename); ... } $user->avatar->removeAll(); $user->avatar = $upload_path.$file[0]; ... $user->save(['quiet'=>true]); The result of which issues two messages: I 've changed the WireUpload.php (I know, but it was a fast fix) to the following: protected function getTargetFilename($filename) { if(!$this->targetFilename) return $filename; // Parse incoming filename $pathInfo = pathinfo($filename); $extension = isset($pathInfo['extension']) ? $pathInfo['extension'] : ''; // Parse the set targetFilename $targetPathInfo = pathinfo($this->targetFilename); $targetExtension = isset($targetPathInfo['extension']) ? $targetPathInfo['extension'] : ''; // Strip off the target’s extension (if any) $base = basename( $this->targetFilename, $targetExtension !== '' ? '.' . $targetExtension : '' ); // Re‑append the incoming file’s extension (if any) return $base . ($extension !== '' ? '.' . $extension : ''); } This runs on Debian 12 Apache2, ProcessWire 3.0.246 Master, php8.4 if it matters. Thanks for your help!
-
@adrian I did a fresh install on localhost and Tracy runs just fine, so there must be something with my server. Although my localhost setup is the same as the server. I'm going to mark this thread as solved.
-
Thanks @adrian! Just an FYI... My server has php tokenizer installed and accessible. Debian 12, php 8.3, mysql 15.1, and apache 2.4 installed Nov '24. I completely uninstalled Tracy, deleted all Tracy related files from the server, and removed all references to Tracy in the DB. I installed Tracy from Modules > New. The Tracy Bar is not displayed at the bottom right of the screen. I went back into Tracy settings and selected the Force superusers into DEVELOPMENT mode. <-- I read somewhere on here about that setting. I submitted that change. The Tracy bar now shows at the bottom right but still displays the previous two errors. I unchecked the Force superuser checkbox and submitted that change. The Tracy bar disappears.
-
It obviously has to be something on my end. You don't need to spend time troubleshooting it since Tracy is just reporting the problem and not failing herself. When I get it sorted, I'll post back. I appreciate your help! Rick
-
Ok, I made the change in PwApiData.php } elseif ($type == 'proceduralFunctions') { $proceduralFunctionsFunctions = $this->getProceduralFunctions('Functions'); $apiData = array('Functions' => isset($proceduralFunctionsFunctions['pwFunctions']) ? $proceduralFunctionsFunctions['pwFunctions'] : array()); if (file_exists($this->wire('config')->paths->core . 'FunctionsAPI.php')) $apiData += array('FunctionsAPI' => $this->getProceduralFunctions('FunctionsAPI')['pwFunctions']); /* elseif($type == 'proceduralFunctions') { $apiData = array('Functions' => $this->getProceduralFunctions('Functions')['pwFunctions']); if(file_exists($this->wire('config')->paths->core . 'FunctionsAPI.php')) $apiData += array('FunctionsAPI' => $this->getProceduralFunctions('FunctionsAPI')['pwFunctions']); */ } ... Cleared DB cache, Refreshed modules, Restarted PW and got the same errors...
-
-
-
Sure thing! Gimme a sec...
-
ProcessWire 3.0.244 PHP 8.3.19
-
lol. You are correct, Sir! This is where I would have told you. 😄 The same error is present. I logged out and shutdown PW and logged back in.
-
Howdy @adrian, I don't know what the previous version was. It was a recent install within a month though. I removed these two resulting rows.