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
extraarray to the movie catalog - Declared
searchcapability withisRequired: false
Understanding isRequired:
false: Search is optional, catalog appears in normal browsingtrue: 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:
GET /catalog/movie/movieCatalog.json(first 100 items)GET /catalog/movie/movieCatalog/skip=100.json(next 100 items)GET /catalog/movie/movieCatalog/skip=200.json(next 100 items)- 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
- Update your manifest with search, genre, and pagination
- Create the necessary catalog files for each feature
- Reinstall your add-on in EMET Surf
- Test search - try searching for "hello" or "jellyfish"
- Test genre filters - browse by Adventure, Sci-Fi, etc.
- 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!