DEV Community

From Afishka to Aticket: Building a multilingual, multi-region ticket network on WordPress

Aticket AI Genereated image
What started as Afishka, a Russian-language guide to events in Israel, evolved into Aticket—a multilingual, multi-region network with localized portals, real-time event data, and affiliate commerce. Under the hood it’s mostly WordPress (yes, really), The Events Calendar, WooCommerce, a handful of custom plugins, and automation glue (Make.com + AI) to keep content fresh and monetization tidy.


The origin story

  • Afishka began as a simple way to surface Russian-language events in Israel.
  • Traffic grew → artists kept touring → partners started asking for other regions → we needed language, currency, and local checkout.
  • Rather than “one mega site,” we went federated: country portals, local language where useful, consistent UX everywhere.

Network map (current snapshot)

Global hubs

  • aticket.net — worldwide
  • aticket.eu — Europe overview

Country/region portals (sample)

  • UK: aticket.uk
  • Germany: atickets.de
  • France: fr.aticket.net
  • Spain: es.aticket.eu
  • Italy: it.aticket.net
  • Netherlands: nl.aticket.eu
  • Belgium: be.aticket.eu
  • Switzerland: ch.aticket.eu
  • Austria: at.aticket.eu
  • Nordics: no.aticket.eu, se.aticket.eu, fi.aticket.eu, dk.aticket.net
  • CEE: cz.afishka.top, pl.afishka.top
  • Israel: aticket.co.il
  • South Africa: za.aticket.net
  • New Zealand: nz.aticket.net
  • UAE: tickets.almaszone.com

Each portal highlights concerts, theatre, comedy, sports, and festivals, with direct links to trusted sellers.


Why WordPress (still)

  • Speed to iterate: custom post types, hooks, and an ecosystem of battle-tested plugins.
  • The Events Calendar for editorial control + structured event data.
  • WooCommerce for checkout flows when needed (e.g., local registrations).
  • Elementor for rapid landing pages that marketing can ship without dev time.
  • Multilingual & Multicurrency for localized prices and language toggles.

This stack let us stay close to the business while shipping fast.


The data layer (APIs, scraping, and “widgetizing”)

  • Ticketmaster Discovery API powers live event data. We wrap it with small “widgets” (shortcodes/blocks) that:
    • fetch events by country/venue/promoter,
    • normalize fields (dates, images, seating notes),
    • and render SEO-friendly cards with canonical links.
  • Custom WordPress scraping plugin (our own) for sources that don’t expose APIs. Requirements we implemented:
    1. Multiple selectors per scraper
    2. Transform scraped data via ChatGPT (titles/descriptions normalization, locale hints)
    3. Create posts directly (no raw store), with a unique field to prevent duplicates
    4. Manual run and scheduled jobs
We never store keys in code, and we rate-limit + cache API responses server-side.

Automation (Make.com + AI)

  • Google Trends → content ideas (spike detection per region/language)
  • AI rewrites/summaries for long bios and event descriptions
  • Telegram publishing: when an event is updated in The Events Calendar, we auto-post to our Telegram channel with emoji, price, start date, canonical link, and a small CTA.
  • Affiliate sync: normalize UTM & sub-IDs, attach to links per region.

i18n & multi-region: what actually mattered

  • RTL/LTR coexistence (Hebrew ↔︎ everything else).
  • Currency switching per region and even per link (for A/B):
// Example: set currency via URL param like ?wcmlc=EUR
add_action('wcml_client_currency', function ($current) {
    return isset($_GET['wcmlc']) ? strtoupper(esc_attr($_GET['wcmlc'])) : $current;
});
  • Slug strategy: keep short, language-native slugs for SEO (city + artist), avoid transliteration soup.
  • Schema: Event and Organization structured data per locale; image sizes consistent.

Performance & reliability

  • We host on multiple providers to keep portals physically close to users.
  • Page caching (e.g., WP Super Cache) + careful JS/CSS minification; exclude fragile scripts (like some Events Calendar widgets) from aggressive optimization when needed.
  • Image sources: prefer provider images (when licensed) and lazy-load everything else.
  • Avoid over-optimizing the admin: editors must be fast, or content dies.

Commerce & payments (when we sell directly)

  • WooCommerce products for specific registrations (e.g., local events with fixed price).
  • Stock = seats; quantity limited (e.g., max 3), with dynamic attendee fields.
  • Thank-you page and flows adapt to product category (“event” vs “merch”).
  • Cardcom gateway in Israel (with category-based operation codes).
  • Single-product per cart for event SKUs to avoid multi-date mix-ups.

Affiliates & attribution

We run an in-house affiliate layer for partner landing pages:

  • 30-day cookie window (overrideable)
  • Simple DB table for leads with timestamps and affiliate IDs
  • “Paid to affiliate” status tracking
  • Manual override trigger for special cases (e.g., sponsor campaigns)

This plays nicely with external affiliate programs (Ticketmaster, Amazon, travel).


Editorial workflow

  • Long-form SEO: artist bios, city guides, seasonal festival pages.
  • Event tables: chronological order (always), price snippets, city filters.
  • Cross-posting to Telegram; planned YouTube Shorts and email “What’s on” digests.
  • Internal links across the network (country page ↔ city page ↔ artist page).
  • Add a subtle footer CTA:
    “Узнай первым о лучших концертах в Израиле: Телеграм канале — https://t.me/firstlineshows

A tiny architecture sketch

flowchart LR
  subgraph Input
    TM[Ticketmaster API]
    Scrapers[Custom Scrapers]
    Trends[Google Trends]
  end

  subgraph WP[WordPress Network]
    TEC[The Events Calendar]
    WC[WooCommerce]
    MU[Multilingual & Multicurrency]
    Widgets[Shortcodes/Widgets]
    AI[ChatGPT transforms]
  end

  subgraph Automation
    Make[Make.com Scenarios]
    TG[Telegram Bot]
  end

  Input --> WP
  WP --> Automation
  Make --> TG
  WP --> Users[Portals by Region/Language]

A few code crumbs

1) “Featured events” RSS with future-date filter

add_action('init', function () {
  add_feed('featured-events', function () {
    header('Content-Type: application/rss+xml; charset=' . get_option('blog_charset'), true);
    $cutoff = (new DateTime(current_time('Y-m-d H:i:s')))->modify('+9 days')->format('Y-m-d H:i:s');

    $q = new WP_Query([
      'post_type' => 'tribe_events',
      'posts_per_rss' => 10,
      'tax_query' => [[
        'taxonomy' => 'post_tag',
        'field' => 'slug',
        'terms' => 'featured',
      ]],
      'meta_query' => [[
        'key' => '_EventStartDate',
        'value' => $cutoff,
        'compare' => '>=',
        'type' => 'DATETIME',
      ]]
    ]);

    echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rss version=\"2.0\">\n<channel>\n";
    echo "<title>Featured Events</title>\n<link>" . esc_url(home_url('/')) . "</link>\n";

    while ($q->have_posts()) {
      $q->the_post();
      $img = get_the_post_thumbnail_url(get_the_ID(), 'large');
      echo "<item>\n<title>" . esc_html(get_the_title()) . "</title>\n";
      echo "<link>" . esc_url(get_permalink()) . "</link>\n";
      if ($img) echo "<enclosure url=\"" . esc_url($img) . "\" type=\"image/jpeg\" />\n";
      echo "<description><![CDATA[" . wp_kses_post(get_the_excerpt()) . "]]></description>\n";
      echo "</item>\n";
    }

    echo "</channel>\n</rss>";
    wp_reset_postdata();
  });
});

2) Category-aware checkout behavior (sketch)

add_filter('woocommerce_add_to_cart_validation', function ($valid, $pid, $qty) {
  // Enforce single event product in cart
  if ($valid && has_term([46], 'product_cat', $pid)) {
    foreach (WC()->cart->get_cart() as $c) {
      if ($c['product_id'] !== $pid && has_term([46], 'product_cat', $c['product_id'])) {
        wc_add_notice(__('You can only choose one event date per order.'), 'error');
        return false;
      }
    }
  }
  return $valid;
}, 10, 3);

What worked (and what didn’t)

Wins

  • Country portals rank faster than a single global site for event queries.
  • Editors can ship fast (Elementor + good component library).
  • Telegram boosts discovery for Russian-speaking audiences.
  • API-first mindset keeps content fresh without burning writers out.

Traps

  • Over-aggressive asset optimization can break event widgets—exclude selectively.
  • Don’t over-centralize slugs: let languages breathe.
  • Affiliate attribution disputes happen: keep logs and add a manual override.

What’s next

  • Better city/venue knowledge graph (dedupe + cross-locale linking).
  • Auto-generate artist landing pages from first-party + API data.
  • Expand short-video workflow (YouTube Shorts/TikTok with safe affiliate framing).
  • A tiny public SDK for our “event widgets” so partners can embed them.

Closing thoughts

You don’t need a greenfield stack to build a global product. We got pretty far with WordPress, a pragmatic plugin set, a few hundred lines of glue code, and consistent editorial + automation habits. If you’re balancing speed, SEO, and monetization, a federated WordPress network is still a wildly productive place to start.

Where to explore (short list)

Happy to answer questions about specific pieces (TEC quirks, Woo flows, Telegram publishing, etc.).

Top comments (0)