Osclass Hooks, Themes, and Plugins (Safe Production Customization)

A developer edits a core template to fix a client request by Friday. Three months later a core update overwrites that file and the fix is gone. Prefer hooks for behavior, child themes for markup, and plugins for billing and spam: each lives under oc-content and can be diffed without touching core. Log which plugin owns each shared hook after every staging pass. File layout: architecture notes, the production build guide, and the official introduction.

Finding and Owning Hooks

Discover hook names by grepping core for osc_run_hook( and osc_apply_filter( under oc-includes/osclass. Do not invent names from memory. Document which plugin owns each shared hook in the release notes.

  • init / init_item / init_user / init_main: early request setup per controller.
  • header / footer / before_html / after_html: assets and late HTML wrappers.
  • before_search / search_conditions / after_search: filter params and result sets on search routes.
  • item_form / item_form_price / item_contact_form: publish, edit, and contact form regions.
  • posted_item / edited_item: after successful save in ItemActions.
  • hook_email_item_inquiry and other hook_email_*: mail side effects after core templates load.
  • add_admin_toolbar_menus / plugin admin menu hooks: backoffice navigation and assets.

Lower priority numbers run earlier (default 5). Example conflict: plugin A and plugin B both attach to item_form_price; if B runs later and echoes a full replacement block, A's note disappears. Fix by agreeing ownership, using different form hooks, or calling osc_remove_hook() on uninstall for callbacks you registered. Prefer named functions so remove and reorder stay possible.

Hooks, Themes, Child Themes, and Plugins

Three layers. Mixing them without a clear owner is how the same business rule ends up twice and breaks after one plugin update. Prefer core helpers (row loaders, cookie/session, search utilities) before inventing parallel queries in a theme.

Osclass hooks and filters flow between core, themes, and plugins in oc-content When to use a theme, plugin, hooks, or avoid editing oc-includes
LayerPurposeExample
HooksChange runtime behavior without editing core controllersitem_form_price, posted_item
Themes / child themesControl UI and layout while preserving upgrade pathOverride a template; keep extras in functions_child.php
PluginsReusable modules such as billing, messaging, anti-spamOsclass Pay; Cloudflare Turnstile

Hooks register with osc_add_hook(). Filters register with osc_add_filter() and must return the transformed value through osc_apply_filter(). Themes and plugins fire side effects with osc_run_hook(). Prefer named plugin functions over anonymous closures.

osc_add_hook('item_form_price', 'myplugin_render_price_note');

function myplugin_render_price_note() {
  echo '<p class="price-note">Price shown excludes delivery.</p>';
}

osc_add_filter('email_title', 'myplugin_prefix_email_title');

function myplugin_prefix_email_title($title) {
  return '[Site] ' . $title;
}

osc_add_hook('search_conditions', 'myplugin_log_search_params');

function myplugin_log_search_params($params) {
  // inspect Params array; do not invent SQL here unless you own indexes
}

Plugins that ship custom mail should create and remove templates through core helpers:

osc_email_template_create(
  'xyz_my_custom_template',
  '{WEB_TITLE} - New info #{KEYWORD0}',
  '<p>Hi {CONTACT_NAME}!</p><p>{KEYWORD1}</p>'
);

// on uninstall or schema cleanup:
osc_email_template_delete('xyz_my_custom_template');

Disable does not uninstall: orphan email templates and preferences stay until you delete them. Use osc_static_page_url_from_page($page, $locale) for static page links so rewrite patterns and locale prefixes match Settings > Permalinks. Hardcoded ?page=page&id= URLs break when friendly URLs turn on.

Theme routes can resolve to a theme file or to that theme's custom or plugins subfolder. Keep business rules out of those templates when a hook can own them.

Child theme load order: parent template → child override of the same path → functions_child.php for hooks and osc_enqueue_style(). Copy only templates you change. Osclass-initiated files (main.php, search.php, item.php, account templates) and theme-initiated includes (header.php, loop-single.php) resolve differently; re-diff overrides after every parent theme update.

function gam_child_custom_css() {
  osc_enqueue_style('style-child', osc_current_web_theme_url('css/style-child.css'));
}
osc_add_hook('header', 'gam_child_custom_css');

Plugin layout: folder under oc-content/plugins/, index registers hooks on activation, admin assets only on plugin admin pages. Loading a payment admin stylesheet on every public page is a common leak that looks like a slow theme. Prefer a three-letter plugin prefix on function names (xyz_) so uninstall and greps stay unambiguous across themes.

Prefer model helpers over ad-hoc SQL against oc_t_item from a theme. Osclass 8.3 session-backed loaders cut repetitive queries. Prefer osc_get_countries() / osc_get_country_row('US') (and matching region, city, category, user helpers) over looping Country::newInstance()->listAll(). Category preload is gated by OPTIMIZE_CATEGORIES and OPTIMIZE_CATEGORIES_LIMIT (roughly 1,000-2,000). Past that limit, themes that assume a full in-memory tree will fail. Flush object cache after taxonomy or preference changes that those helpers cache in session.

Put business rules in a plugin under oc-content/plugins/, not in parent functions.php. Parent theme updates can overwrite that file; child functions_child.php is for presentation hooks and CSS enqueue only. If a rule must survive theme swaps (fee labels, form validation, mail), it belongs in a plugin with install/uninstall cleanup.

Plugin install should create email templates and preferences you need; uninstall should delete those templates and prefs. Disable leaves files on disk and usually keeps settings, so a "disabled" payment plugin can still confuse operators who expect a clean slate. Document which tables or preference keys your plugin owns. After activate, run publish and search once before enabling the plugin on production.

Market Installs and Renamed Backoffice

Paste an OsclassPoint API key into Settings > General > Software Updates to install themes and plugins from Market. Language and location packs work without a key. Treat the key as a credential; rotate it when staff with Market access leave; still stage Market installs like a ZIP upload against your PHP minor and active plugin set. Market delivery does not prove payment callbacks or cron ownership.

Since Osclass 8.0 you can rename oc-admin on disk and set OC_ADMIN_FOLDER in config.php. Plugin admin links must use osc_admin_base_url(), not a hardcoded /oc-admin/ path. Do not put the new folder name in robots.txt. After rename, click every plugin admin menu once on staging; broken links usually mean a plugin still concatenates a literal path. Update operator bookmarks and staging deploy runbooks to the new backoffice folder name in the same release. Docs: change backoffice directory name.

Troubleshooting Customization Failures

Deploy one high-impact change at a time and verify publish, pay, search, message, and moderate. Keep a runbook that names the payment plugin, cache plugin, and hooks that touch publish.

  • Blank admin page: syntax or runtime error in plugin bootstrap; enable error logging and disable the last activated plugin first.
  • Listing form corruption: multiple hooks mutating the same form region without agreed priority; re-enable one plugin at a time on staging.
  • Webhook or payment issues: custom override changed the callback route, HTTPS redirect, or expected status values.
  • Cache or session bugs: dynamic account widgets cached as static HTML for guests; exclude login, publish, dashboard, and payment callbacks from full-page HTML cache.
  • Permission errors: plugin writes under oc-content without matching deploy user ownership on uploads and cache dirs.
  • Image upload 500 with files in temp: raise OSC_MEMORY_LIMIT in config.php (for example 128M) within host PHP max; default core floor is 64M.
  • SEO route regressions: custom rewrite rules creating duplicate indexable URLs; check canonical tags after rewrite changes.
  • PHP mismatch errors: plugin uses syntax unsupported on the production PHP minor.
  • Sudden logout after subdomain settings change: Osclass drops front-end session and cookie values so an old cookie domain cannot leave accounts stuck. Expect to sign in again; it is intentional cleanup.

Fork core only if hooks and plugins cannot do the job and someone will merge every upstream release. Stay on supported core; treat upload and plugin paths as high-risk in review (older Osclass 3.x had documented RCE via admin XSS and crafted uploads). Footer script moves from old speed tutorials repeatedly broke item-post uploads and city autosuggest; retest those flows after asset-order changes. Email customization needs a working SMTP path, not only a template edit. Generated hook names, table names, and preference keys are guesses until you grep core or read docs; keep config.php and Market keys out of chat logs.

Translating Themes and Plugins

Translations use .po/.mo files. Never edit the en_US source catalogs; work on a copy of the target language in oc-admin (International > Translations) or Poedit, then compile to .mo. Themes and plugins ship their own catalogs under their folders; leave core catalogs alone unless you maintain a language pack. Market language packs install without an OsclassPoint API key.

RTL locales need a theme that flips layout, not only translated strings. After enabling an RTL language, check listing forms, filters, and oc-admin labels on a phone-width viewport. Incomplete packs often leave mixed English admin labels next to translated front-office strings; decide whether that is acceptable before launch. Keep permalink and language-in-URL settings stable before marketing spend so translated routes do not fork.

Maintenance Workflow and Release Safety

Keep custom plugins and child themes in version control. Each release names the hook or template touched, the reason, and how to roll back. Before production: staging on a recent DB dump, verified backup restore, PHP compatibility for every active plugin, dry run of publish, search, payment callback, and moderation. After rewrite changes, confirm canonical tags on listing URLs.

Osclass 8.3.1 added PHP 8.5 support, an updated PHP mailer path, utf8mb4 (emoji and full Unicode in titles, messages, and category names), and session/cookie updates. Older utf8 collations can truncate emoji on write. Core PHP support does not certify every theme or plugin on that minor; check each product's Requires-PHP note. Keep web and CLI PHP identical for cron. After upgrade, sign in as user and admin, publish a listing with emoji in the title, open Settings > Permalinks and Save once, and open a session-dependent dashboard widget. Session loops after a domain move often mean cookie domain or reverse-proxy Set-Cookie rewrites, not a theme bug.

Release gate: named owner; changelog and rollback note; no core edits without sign-off; hook priorities written down when plugins share a flow; PHP compatibility matrix updated. Monthly: review plugin changelogs against your PHP minor; re-test payment callbacks after proxy or SSL changes; confirm cron CLI PHP matches the web pool; sample customized templates after a parent theme update. Keep a compatibility matrix (PHP minor, Osclass, theme, payment plugin, last staging pass). If the matrix is stale, force a full staging pass even for a "small" plugin bump. After parent theme updates, diff every child override file against the new parent before calling the release done; silent template renames are a common source of blank listing cards.

About the author

Oliver Bk

I'm Oliver Bk. I build classifieds marketplaces and the scripts around them - imports, crawlers, payment hooks, cleanup jobs that should have shipped in core. Day to day that's PHP, HTML, CSS, and JavaScript; Python when listing data needs scraping or reshaping before it lands in Osclass.

These articles come from live projects: what broke, what the fix required, what staging should have caught. Each page is reviewed against Osclass product behavior (oc-admin paths, cron, plugins) before publish. A fair share of my fixes still start with a bug report, coffee, and a script that was only meant to run once. See more of my writing on the OsclassPoint blog or my code on GitHub.

This article was last updated on 25. August 2026.

Frequently asked questions

Does Osclass support PHP 8.5?
Yes. Full PHP 8.5 support shipped in Osclass 8.3.1 (January 2026), with cookie/session updates and utf8mb4. Enable mbstring. Core support does not mean every theme or plugin is certified on that minor; check each Requires-PHP note and smoke-test on staging.
How do I connect my Osclass backoffice to OsclassPoint?
Generate an API key in the OsclassPoint account profile, paste it under Settings > General > Software Updates in Osclass, and validate it. Market then installs and updates themes and plugins from the backoffice. Language and location packs do not require an API key.
How do I translate an Osclass site into another language?
Use built-in International > Translations or edit standard .po/.mo catalogs with Poedit, an agency, a coworker, or an AI-assisted workflow, then compile .mo files. Never change en_US source strings directly. Market offers tens of language packs (docs cite 40+), and Provide to Community shares improvements. Pair languages with country geolocation SQL packs for accurate region and city filters.
How can AI coding tools help with Osclass development?
Open the real Osclass tree in an editor with an AI agent (Cursor or similar), constrain it with rules that forbid casual core edits and require PHP 7.4+ plugin/theme boundaries, and use it to search hooks, draft child-theme helpers, and explain failures. Verify every generated API name against core or docs, keep secrets out of chat, and always run publish/search/pay checks on staging.
Can I rename the oc-admin folder?
Yes, since Osclass 8.0. Rename the folder on disk and set OC_ADMIN_FOLDER in config.php to the new name. Update plugins that hardcode /oc-admin/ so they call osc_admin_base_url() instead.
Do old plugins and themes still work on current Osclass?
Hook-based plugins and themes from years earlier commonly keep working on Osclass 8.4.x when they avoid hardcoding removed APIs and stay out of core files. Always smoke-test publish, search, and payments on staging after a core bump.