Skip to main content

Dynamic content (search, filters, pagination)

Amazing! Your add-on now provides movies and TV shows with full functionality. But what if users want to find specific content? Let's add dynamic features like search, filtering, and pagination to make your content more discoverable.

These features make your add-on much more user-friendly by helping users find exactly what they're looking for.

Understanding dynamic features

Why dynamic content matters:

  • Search: Users can find content by typing keywords
  • Filters: Users can browse by genre, year, rating, etc.
  • Pagination: Handle large catalogs efficiently
  • Better UX: Users spend less time browsing and more time watching

Adding search functionality

Search allows users to find content by typing keywords. To enable search, you need to declare it in your catalog configuration.

Update your manifest

Add search capability to your movie catalog:

{
"id": "my.first.emet.addon",
"version": "1.0.0",
"name": "Hello, World",
"description": "My first EMET Surf add-on",
"logo": "https://example.com/logo-256.png",
"resources": [
"catalog",
{
"name": "meta",
"types": ["movie", "series"],
"idPrefixes": ["hiwrld_"]
},
"stream"
],
"types": ["movie", "series"],
"catalogs": [
{
"id": "movieCatalog",
"type": "movie",
"name": "Hello, Movies",
"extra": [
{ "name": "search", "isRequired": false }
]
},
{"id": "seriesCatalog", "type": "series", "name": "Hello, TV Shows"}
]
}

What changed:

  • Added extra array to the movie catalog
  • Declared search capability with isRequired: false

Understanding isRequired:

  • false: Search is optional, catalog appears in normal browsing
  • true: Search is required, catalog only appears in search results

How search works

When users search, EMET Surf will request:

GET /catalog/movie/movieCatalog/search=jellyfish.json

You need to create a file that matches this pattern: catalog/movie/movieCatalog/search=query.json

Creating search results

Create the search directory structure:

On Windows:

mkdir catalog\movie\movieCatalog

On Mac/Linux:

mkdir -p catalog/movie/movieCatalog

Create a sample search result file catalog/movie/movieCatalog/search=hello.json:

{
"metas": [
{
"type": "movie",
"id": "tt0032138",
"name": "The Wizard of Oz",
"poster": "https://images.metahub.space/poster/medium/tt0032138/img",
"genres": ["Adventure", "Family", "Fantasy", "Musical"]
},
{
"id": "hiwrld_jellyfish",
"type": "movie",
"name": "Jellyfish",
"poster": "https://images.unsplash.com/photo-1496108493338-3b30de66f9be",
"genres": ["Demo", "Nature"]
}
]
}

Note: In a real add-on, you'd implement dynamic search that generates results based on the query.

Adding genre filters

Genre filters let users browse content by category. You need to declare supported genres and create filtered catalogs.

Update manifest with genres

{
"catalogs": [
{
"id": "movieCatalog",
"type": "movie",
"name": "Hello, Movies",
"extra": [
{ "name": "search", "isRequired": false },
{ "name": "genre", "isRequired": false }
],
"genres": ["Adventure", "Family", "Sci-Fi", "Demo"]
},
{"id": "seriesCatalog", "type": "series", "name": "Hello, TV Shows"}
]
}

Important: Only list genres you can actually provide filtered results for.

Creating genre-filtered catalogs

Create separate catalog files for each genre:

Adventure genre - catalog/movie/movieCatalog/genre=Adventure.json:

{
"metas": [
{
"type": "movie",
"id": "tt0032138",
"name": "The Wizard of Oz",
"poster": "https://images.metahub.space/poster/medium/tt0032138/img",
"genres": ["Adventure", "Family", "Fantasy", "Musical"]
}
]
}

Sci-Fi genre - catalog/movie/movieCatalog/genre=Sci-Fi.json:

{
"metas": [
{
"type": "movie",
"id": "tt0017136",
"name": "Metropolis",
"poster": "https://images.metahub.space/poster/medium/tt0017136/img",
"genres": ["Drama", "Sci-Fi"]
}
]
}

Family genre - catalog/movie/movieCatalog/genre=Family.json:

{
"metas": [
{
"type": "movie",
"id": "tt0032138",
"name": "The Wizard of Oz",
"poster": "https://images.metahub.space/poster/medium/tt0032138/img",
"genres": ["Adventure", "Family", "Fantasy", "Musical"]
},
{
"id": "hiwrld_jellyfish",
"type": "movie",
"name": "Jellyfish",
"poster": "https://images.unsplash.com/photo-1496108493338-3b30de66f9be",
"genres": ["Demo", "Nature"]
}
]
}

Handling empty genres

If you declare a genre but don't have content for it, create an empty catalog:

Demo genre - catalog/movie/movieCatalog/genre=Demo.json:

{
"metas": []
}

Important: Always provide a valid response for declared genres to avoid errors.

Adding pagination

Pagination helps handle large catalogs by loading content in chunks. Users scroll, and more content loads automatically.

Update manifest for pagination

{
"catalogs": [
{
"id": "movieCatalog",
"type": "movie",
"name": "Hello, Movies",
"extra": [
{ "name": "search", "isRequired": false },
{ "name": "genre", "isRequired": false },
{ "name": "skip", "isRequired": false }
],
"genres": ["Adventure", "Family", "Sci-Fi", "Demo"]
},
{"id": "seriesCatalog", "type": "series", "name": "Hello, TV Shows"}
]
}

How pagination works

EMET Surf requests pages sequentially:

  1. GET /catalog/movie/movieCatalog.json (first 100 items)
  2. GET /catalog/movie/movieCatalog/skip=100.json (next 100 items)
  3. GET /catalog/movie/movieCatalog/skip=200.json (next 100 items)
  4. Continue until you return an empty catalog

Creating paginated catalogs

First page - catalog/movie/movieCatalog.json (your existing catalog):

{
"metas": [
// Your first 100 items
]
}

Second page - catalog/movie/movieCatalog/skip=100.json:

{
"metas": [
// Items 101-200
]
}

Last page - return empty when no more content:

{
"metas": []
}

Advanced filtering features

EMET Surf supports many advanced filtering options. Declare them in your manifest:

{
"extraSupported": [
"genreMulti", // Multiple genre selection
"genreExclude", // Exclude genres
"releaseYear", // Filter by year
"originalLanguage", // Filter by language
"releaseDateRange", // Date range filtering
"tmdbRatingRange", // Rating range filtering
"productionCountry", // Country filtering
"pagination" // Pagination metadata
],
"catalogs": [
{
"id": "movieCatalog",
"type": "movie",
"name": "Hello, Movies",
"extraSupported": ["pagination"]
}
]
}

Example advanced filter requests

When you declare these features, EMET Surf may request:

/catalog/movie/movieCatalog/genre=Action,Fantasy.json          # Multiple genres
/catalog/movie/movieCatalog/genreExclude=Horror.json # Exclude genres
/catalog/movie/movieCatalog/releaseYear=2024.json # Year filter
/catalog/movie/movieCatalog/releaseDateGte=2023-06-01.json # Date range
/catalog/movie/movieCatalog/ratingTmdbGte=4.2&ratingTmdbLte=6.5.json # Rating range
/catalog/movie/movieCatalog/productionCountry=US,GB.json # Country filter
/catalog/movie/movieCatalog/language=es.json # Language filter

Pagination metadata

For better pagination, include metadata in your responses:

{
"page": 2,
"totalPages": 12,
"metas": [
// Your content
]
}

Testing dynamic features

  1. Update your manifest with search, genre, and pagination
  2. Create the necessary catalog files for each feature
  3. Reinstall your add-on in EMET Surf
  4. Test search - try searching for "hello" or "jellyfish"
  5. Test genre filters - browse by Adventure, Sci-Fi, etc.
  6. Check server logs - you'll see requests for different filters

What you've accomplished

  • Added search functionality to your add-on
  • Implemented genre-based filtering
  • Added pagination support for large catalogs
  • Learned about advanced filtering options
  • Understood dynamic content patterns
  • Created a more user-friendly experience

What's next?

Your add-on is now feature-complete! Users can browse, search, filter, and watch content. In the next step, we'll learn about Media Portals - complete add-ons that provide comprehensive content libraries.

Summary

  • Search helps users find specific content
  • Genre filters organize content by category
  • Pagination handles large catalogs efficiently
  • Declare capabilities in your manifest
  • Create corresponding catalog files
  • Always provide valid responses for declared features
  • Your add-on now provides a professional user experience!