CodeOn Core
Codeon Core Free Plugin
by CodeOn (Samsiani) · github.com/samsiani/codeon-core · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/samsiani/codeon-core/releases/download/v0.3.19/codeon-core-v0.3.19.zipReadme
=== CodeOn Core === Contributors: samsiani Tags: woocommerce, georgia, address, checkout, location Requires at least: 6.2 Tested up to: 6.9 Requires PHP: 8.1 Requires Plugins: woocommerce Stable tag: 0.3.19 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html
Georgian Locations for WooCommerce — cascading Region → Municipality → Settlement address picker. 4,394 settlements bundled.
== Description ==
WooCommerce out of the box has no idea what a Georgian city is. Customers type their settlement name freehand, with five different spellings, in three languages. Reports are useless. Couriers reject orders.
CodeOn Core ships the entire administrative hierarchy of Georgia — 13 regions, 77 municipalities, 4,394 settlements (cities, towns, villages) — as a structured, cascading checkout dropdown.
Customers select Region → Municipality → Settlement. Validated server-side. Stored as structured order meta. Filterable in the admin orders list. Compatible with classic checkout (block checkout in v0.2.0).
= What you get =
- Cascading address picker on classic WooCommerce checkout (block-checkout coming in v0.2)
- 4,394 Georgian settlements, fully bilingual (Georgian + Latin transliteration)
- Region dropdown aligned with WooCommerce's existing Georgia state codes (TB, AJ, IM, …) — no breaking changes for existing orders
- REST API for typeahead search & cascade lookups
- HPOS-compatible structured order meta
- Custom Georgian address format on emails, invoices, and the My Account page
- Toggle to hide occupied territories (Abkhazia, Tskhinvali region) — hidden by default
- Display mode setting: Always Georgian, Always English (transliterated), or Bilingual ("კონდოლი (Kondoli)")
= What you don't get =
- No upsells in the checkout flow.
- No phoning home.
- No mandatory account creation.
= About CodeOn =
CodeOn Core also acts as the canonical home for the CodeOn family of premium WooCommerce plugins (TBC Card, BOG Card, Flitt, and others). When a CodeOn premium plugin is installed alongside Core, both share a single tidy admin menu instead of cluttering the sidebar. Premium plugins are sold separately at codeon.ge — they are not required for the locations feature.
== Installation ==
- Install via Plugins → Add New → search for "CodeOn Core" → Install → Activate.
- WooCommerce → CodeOn → Locations to configure display mode and toggle occupied territories.
- That's it. The checkout cascade activates automatically when a customer selects Georgia as their country.
== Frequently Asked Questions ==
= Does it work with the WooCommerce Checkout block? =
Block checkout support arrives in v0.2.0 (next release). v0.1 supports the classic shortcode-based checkout.
= Does it conflict with my existing Georgia state codes? =
No. We preserve WooCommerce's existing 12 GE state codes (TB, AJ, IM, …) and only add TS for the Tskhinvali region. Existing orders continue to validate.
= Will villages I'm missing be added? =
The dataset comes from ka.wikipedia.org categorized by municipality. Open an issue at our GitHub if a village is wrong or missing — we re-sync on every plugin release.
= Are occupied territories included? =
Yes — Abkhazia and the Tskhinvali region are in the dataset but hidden by default. Enable them in the settings if your store ships there.
== Screenshots ==
- Cascading address picker on the WooCommerce checkout — Region, Municipality, Settlement.
- Diagnostics tab showing dataset size and version.
- CodeOn hub menu with installed plugins listed underneath.
== Changelog ==
= 0.3.19 — 2026-05-21 =
- No-op bump so sites already on v0.3.18 see a fresh update line. The v0.3.18 icon-injection fix now propagates on the next force-check.
= 0.3.18 — 2026-05-21 =
- Fix: plugin icon + banner now actually show on Dashboard → Updates and in the "View details" modal. The artwork has shipped inside the plugin ZIP since v0.3.14, but WordPress couldn't see it — PUC (the GitHub-update bridge) doesn't auto-discover
assets/icon/*files. Added apuc_request_info_result-codeon-corefilter that injects the icon + banner URLs into the update payload. Previous attempts (v0.3.15 / 16 / 17) were no-op version bumps that couldn't have fixed this — the URLs weren't in the response at all.
= 0.3.17 — 2026-05-21 =
- Third no-op bump so installs that already pulled v0.3.16 see a fresh update line on Dashboard → Updates. No code, asset, or config change.
= 0.3.16 — 2026-05-21 =
- Second no-op bump to flush WordPress's plugin-card cache. v0.3.15 didn't re-paint the icon on some sites because WP also caches the per-plugin transient that holds the icon URL — bumping the version a second time invalidates that secondary cache layer.
= 0.3.15 — 2026-05-21 =
- No-op release to flush WordPress's plugin-card cache so the refreshed v0.3.14 icon + banner artwork shows up immediately on every merchant's Dashboard → Updates and Add New screens instead of after WP's next scheduled metadata refresh.
= 0.3.14 — 2026-05-21 =
- New: refreshed plugin icon + banner artwork. Glyph is now a stylized "C" with the CodeOn brand-mark dot inside its opening — reads as "the canonical CodeOn plugin" instead of the previous location-pin (which was misleading: CodeOn Core is the free hub for the whole plugin family, Georgian Locations is one feature among several planned). Family-consistent: deep-blue gradient + CodeOn corner mark held invariant per CODEON_PLUGIN_ICON_SYSTEM.md.
- Update: banner subtitle now reads "The canonical hub for the CodeOn plugin family" with a feature strip that covers the broader scope ("PLUGIN HUB · GEORGIAN LOCATIONS · CHECKOUT FIELDS · MORE TO COME") rather than implying the plugin is locations-only.
= 0.3.13 — 2026-05-21 =
- Hygiene: bump bundled
codeon/frameworkfrom 0.3.16 → 0.3.18 for parity with the rest of the CodeOn plugin suite. No behavioural change — CodeOn Core is free and has no license enforcement to gate.
= 0.3.12 — 2026-05-11 =
-
Area position survives WC's client-side resort. The previous releases had Area at the correct DOM position (right after Country) — but
assets/js/frontend/address-i18n.js(shipped by WooCommerce itself) re-sorts checkout fields bydata-priorityon everycountry_to_state_changingevent, reading the priorities fromwc_address_i18n_params.locale.default. Those localised priorities still carried WC's untouched defaultcity: 70, so on every country pick WC's own JS re-tagged Area with priority 70 and moved it to between Address-line-2 (60) and State (80). That's what the merchant kept screenshotting.Fix: also set the unprefixed
default.city.priorityanddefault.state.priorityin thewoocommerce_default_address_fieldsfilter, AND add aprioritykey to the GE-specific override inwoocommerce_get_country_locale. Both filters feedwc_address_i18n_paramsdirectly, so the JS now reads Area at prioritycountry_priority + 1and the resort puts it back where the PHP rendered it. Reads country's actual priority at filter time so it works under any theme (Woodmart, default, custom) that may have re-mapped country. -
Plugin survey: also reviewed every other active hook on
woocommerce_checkout_fields/woocommerce_default_address_fields/woocommerce_get_country_localeon the live install. The Personal-ID field plugins (balance-sync, fina-sync) add fields without specifying a priority for the filter callback — they don't re-order, no conflict with Area positioning. Woodmart's checkout-fields-manager hooks at priority 99999 but its frontend JS only modifies the "required" badge, not the DOM order.
= 0.3.11 — 2026-05-11 =
-
Area now sits truly right-after-Country, even when a theme remaps Country's priority. On artcase.ge a live
WC_Checkout::get_checkout_fields('billing')dump showed:billing_first_namepriority 10 (was 20 by default — Woodmart / Personal-ID plugin remapped it)billing_city(Area) priority 11 (our v0.3.10 value)billing_countrypriority 40 (was 10 by default — also remapped)
My hard-coded
priority = 11put Area between first_name (10) and last_name (20) — visually "right after first name", not what the merchant wanted. Fix: read whatever priority Country ended up at AFTER all other filters have run (we still hookwoocommerce_checkout_fieldsat priority 100000, and the WC 10.7 source confirmsuasort()runs AFTER our filter) and set Area tocountry.priority + 1. State (hidden, auto-filled) getscountry.priority + 2. Now Area renders immediately under Country regardless of what other plugins decided Country's priority should be. -
Shipping-zone "Add region" no longer hides 10 of the 13 Georgian regions. v0.3.2's Tbilisi-mode override trimmed
woocommerce_states['GE']to only the merchant's allowed area codes — which also applied to WP-admin → WC → Settings → Shipping → Add region. Removed the filter; the GE state catalog stays intact globally. The state field at checkout is still hidden via CSS + auto-filled, which is all Tbilisi mode actually needs.
= 0.3.10 — 2026-05-11 =
- Area field now renders immediately under Country / Region on checkout. Previously the
priority = 11change was applied inenforceFinalFieldSetup(hooked atwoocommerce_checkout_fieldspriority 100000) — but WC'sWC_Checkout::get_checkout_fields()runsuasort()on each fieldset BEFORE applying that filter, so the late priority change had no effect on render order. Moved the priority assignment to the earlierwoocommerce_default_address_fields+woocommerce_billing_fields/woocommerce_shipping_fieldsfilters, which run before WC's sort, so Area now lands right after Country exactly as configured. - Admin Surroundings picker is Georgian-only. No more redundant labels like "ნორიო (გარდაბნის მუნიციპალიტეტი) (Norio (gardabnis munitsipaliteti))" — the trailing Latin transliteration is dropped both for pre-rendered selected pills AND for AJAX search results. The customer-facing Area dropdown still honours the merchant's
display_modesetting; this change only affects the admin picker.
= 0.3.9 — 2026-05-11 =
- Surroundings-picker pill polish per merchant feedback:
- Removed
line-height: 1from the scoped remove-× rule so the × is no longer cropped vertically (was overriding the natural pill line-height). - Neutralised Select2 v4.1.0-rc.0's default
border-right: 1px solid #aaaon.select2-selection__choice__remove— the ugly faux-separator between × and pill text is gone. - Bumped the choice's
padding-leftto20px !importantso the × has visible breathing room from the pill's left edge.
- Removed
- Headless-verified the three computed values before tagging (
paddingLeft: 20px,borderRight: 0px none,lineHeight: normal).
= 0.3.8 — 2026-05-11 =
- Surroundings picker pills no longer spill outside the box. Root cause was twofold:
Select2 v4.1.0-rc.0'scontainerCssClassoption silently dropped on init — so every CSS rule I'd scoped to.codeon-tbilisi-pickernever matched the rendered container, and Select2's tight defaults applied unmodified. Now adding the scoping class manually via$sel.next('.select2-container').addClass(...)immediately after init, guaranteed to take effect.- The fallback CSS used
float: lefton pills with adisplay: blockparent<ul>— classic float-containment problem (parent height collapses, pills overflow downward). Switched todisplay: flex; flex-wrap: wrap; gap: 6pxon the<ul>withfloat: none; flex: 0 0 autoon the pills. Parent now grows organically as pills wrap.
- Typed text in the search input is now unambiguously visible. The search
<li>isflex: 1 0 100%so it always wraps to its own line below the pills. The<input>inside iswidth: 100%,min-height: 40px,font-size: 14px,color: #0b0f19,background: #fff, with a 1px visible border and brand focus ring. No more typing into invisible 0-px inputs. - Headless verified before tagging. Built a puppeteer rig that loads the picker with 10 pre-selected pills, then types "gant" into the empty-state search field. Measured: 0 pills outside the container bounds, search input box is 684×40px, typed text colour is
rgb(11,15,25), backgroundrgb(255,255,255), font size 14px. Both screenshots inspected (/tmp/picker-1-initial.png,/tmp/picker-2-typing-empty.png) — pills wrap inside, typed text is clearly readable.
= 0.3.7 — 2026-05-11 =
- Surroundings picker UX polish, modelled after WooCommerce's country selector.
- Search input now sits on its own full-width row below the pills with a visible white background + light border. Typed text is unambiguously readable — fixes the "I can't see what I'm typing" report.
- Container background is light grey (
--bg-muted) so the white pills + white search row read as distinct surfaces inside the picker. - Container grows downward smoothly as pills wrap; no more pills falling outside the visible border.
- Dropped the redundant
" — Muni, Region"suffix that the picker was appending to every result. The dataset'sname_kaalready disambiguates similarly-named villages with(<muni>)in parens — appending the slugs on top produced labels like "არაშენდა (მცხეთის მუნიციპალიტეტი) — მცხეთის მუნიციპალიტეტი, მცხეთა-მთიანეთი". Now you just get "არაშენდა (მცხეთის მუნიციპალიტეტი)".
- Area field repositioned on checkout. Was rendering at priority 47 (between Company and Address line 1). Moved to priority 11 — sits immediately after Country / Region as the merchant requested. Hidden state field moved to priority 12 to stay paired with country in case any theme renders hidden rows.
- The customer-facing Area dropdown labels also lost the redundant " — Muni, Region" suffix for the same dataset-disambiguation reason.
= 0.3.6 — 2026-05-11 =
- Surroundings multiselect now actually persists picked settlements. The framework's
FieldValidator::process()explic
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v0.3.19 | May 21, 2026 | codeon-core-v0.3.19.zip | 54 |
| v0.3.18 | May 21, 2026 | codeon-core-v0.3.18.zip | 1 |
| v0.3.17 | May 21, 2026 | codeon-core-v0.3.17.zip | 0 |
| v0.3.16 | May 21, 2026 | codeon-core-v0.3.16.zip | 2 |
| v0.3.15 | May 21, 2026 | codeon-core-v0.3.15.zip | 1 |
| v0.3.14 | May 21, 2026 | codeon-core-v0.3.14.zip | 0 |
| v0.3.13 | May 21, 2026 | codeon-core-v0.3.13.zip | 0 |
| v0.3.12 | May 10, 2026 | codeon-core-v0.3.12.zip | 15 |
| v0.3.11 | May 10, 2026 | codeon-core-v0.3.11.zip | 1 |
| v0.3.10 | May 10, 2026 | codeon-core-v0.3.10.zip | 3 |
| v0.3.9 | May 10, 2026 | codeon-core-v0.3.9.zip | 3 |
| v0.3.8 | May 10, 2026 | codeon-core-v0.3.8.zip | 1 |
| v0.3.7 | May 10, 2026 | codeon-core-v0.3.7.zip | 1 |
| v0.3.6 | May 10, 2026 | codeon-core-v0.3.6.zip | 1 |
| v0.3.5 | May 10, 2026 | codeon-core-v0.3.5.zip | 1 |
| v0.3.4 | May 10, 2026 | codeon-core-v0.3.4.zip | 1 |
| v0.3.3 | May 10, 2026 | codeon-core-v0.3.3.zip | 3 |
| v0.3.2 | May 10, 2026 | codeon-core-v0.3.2.zip | 1 |
| v0.3.1 | May 10, 2026 | codeon-core-v0.3.1.zip | 1 |
| v0.3.0 | May 10, 2026 | codeon-core-v0.3.0.zip | 1 |
| v0.2.9 | May 8, 2026 | codeon-core-v0.2.9.zip | 5 |
| v0.2.8 | May 8, 2026 | codeon-core-v0.2.8.zip | 1 |
| v0.2.7 | May 8, 2026 | codeon-core-v0.2.7.zip | 1 |
| v0.2.6 | May 8, 2026 | codeon-core-v0.2.6.zip | 1 |
| v0.2.5 | May 8, 2026 | codeon-core-v0.2.5.zip | 1 |