Configuration
Below is an example of Dexter's default settings. When installed, a new dexter.php file will be added to your system/user/config/ directory with basic configuration. Review the default config below to determine which customization you're going to make. You do not have to copy the entire array. Array keys not found in your dexter.php file will fall back to the default values.
A minimal configuration using Meilisearch locally with DDEV would look like this. Choose which provider to use, give it the credentials, maybe set an environment name, which is used as all the index name prefixes, and then choose what to index and which index name to insert into. By default all fields will be indexed unless you define any indexableFields.
<?php
return [
'provider' => 'meilisearch',
'meilisearch' => [
'url' => 'https://meilisearch-index-url.com:7700',
'appKey' => 'ddev',
],
'env' => 'prod',
'indices' => [
'entries' => [
'exhibit' => 'exhibits',
'work' => 'collections',
'exhibitions' => 'exhibitions',
'newsArticle' => 'news_articles',
],
'categories' => [
'newsCategory' => 'news_categories',
],
'files' => [
'images' => 'images',
'digitalOcean' => 'images',
],
'users' => [
'contentManagers' => 'users',
]
],
];Using the system/user/config/dexter.php file is preferred as it helps keep things separate and tidy, but if you prefer to use the main system/user/config/config.php file you can still do that. You will just need to define the settings under the dexter scope. For example:
<?php
$config['dexter'] = [
'provider' => 'meilisearch',
...
];The full default config from system/user/addons/dexter/settings.php
<?php
/**
* DO NOT EDIT THIS FILE DIRECTLY.
*
* Copy this file to your /system/user/config directory and rename it to config.dexter.php
* to override the default settings. You can remove any settings you don't want to change,
* and they will fall back to the defaults defined here.
*/
return [
// Choose which provider you're using.
'provider' => 'meilisearch', // or "algolia"
// Then set the required config values for it.
'algolia' => [
'appId' => '',
'apiKey' => '',
'mode' => 'keywordSearch', // or neuralSearch if using the Premium or Elevate plans.
],
'meilisearch' => [
'url' => '',
'appKey' => '',
],
// A prefix will be added to each index based on the environment. If you're using EEs .env.php file, you can
// set this to $_ENV['ENVIRONMENT'] to read from the .env.php file.
'env' => 'test',
// Add a suffix to the end of all indices. Useful for multilingual sites.
// If you are using Publisher this value should be left blank as it will automatically be updated.
// Can be a string or a callable function. For example:
/*
'suffix' => function (...$args) {
$request = ee('publisher:Request');
$lang = $request->getCurrentLanguage();
return '_' . $lang->getShortName();
},
*/
'suffix' => '',
// Add the group ID(s) to be used to construct a menu a hierarchical menus, specifically
// designed to render output necessary for Algolia's React HierarchicalMenu component
// https://www.algolia.com/doc/api-reference/widgets/hierarchical-menu/react/
'categoryMenuGroups' => [],
// Any other category groups. Will index with the group name as the object key, and each
// assigned category within the group with its ID and name.
'categoryGroups' => [],
// Similar to categoryGroups where you add the group ID to this config array, but will index
// as a flat list of categories in an array, regardless of the group.
'categories' => [],
// A list of field names to be indexed. If nothing is defined, everything will be indexed.
'indexableFields' => [
//'entries' => [
// 'title',
// 'fluid_field', // Index fluid_field and all nested fields.
// 'fluid_field.*.fields.heading', // Index just the heading field of each content block.
//],
// The above will apply to all entries. If you want different fields for specific channels, use the following format:
//'entries[channel_1]' => [
//],
//'categories' => [
//],
//'categories[group_3]' => [
//],
//'files' => [
//],
//'files[upload_dir_5]' => [
//],
//'users' => [
//],
//'users[member_group_7]' => [
//],
],
// Required - only entries within the defined channels will be indexed. Files from upload destinations can
// also be indexed. In the example below, the numerical value at the end is the channel ID or upload directory ID.
// Since channel names can change, and upload directories don't have short names, Dexter uses their respective IDs.
// Dexter cannot target specific subdirectories within an upload destination.
'indices' => [
'entries' => [
// Multiple channels can add content to the same index
// 'channel_1' => 'index_one',
// 'channel_7' => 'index_one',
// 'channel_8' => 'index_two',
],
'files' => [
// 'upload_dir_5' => 'images',
// 'upload_dir_10' => 'documents',
],
'categories' => [
// 'group_3' => 'categories_index',
],
'members' => [
// 'member_group_4' => 'members_index',
],
],
// Adds a __full_text property when indexing entries, which is a conglomeration of all text found in individual
// fields being indexed. Useful for full-text searching and required if you are using the FileDescribePipeline.
'includeFullText' => true,
// Custom pipelines for additional customization.
// Need to be properly namespaced, but can be loaded from anywhere.
'entryPipelines' => [
// MyCustomPipeline::class,
// \BoldMinded\DexterPipelines\Pipelines\ExamplePipeline::class,
],
// Pipelines applied only when indexing categories.
'categoryPipelines' => [
// MyCustomCategoryPipeline::class,
],
// Pipelines applied only when indexing files.
'filePipelines' => [
// MyCustomFilePipeline::class,
// \BoldMinded\Dexter\Service\Pipeline\FileDescribePipeline::class,
],
'memberPipelines' => [
// MyCustomMemberPipeline::class,
],
// If indexing files, and a pdf, txt, csv, or other text-based file is uploaded it will try to scrape the contents
// of the file and add it to the __full_text property.
'parseDocumentContents' => [
'enabled' => true,
'describePrompt' => 'Summarize this text.',
'maxPages' => 5, // Limit the number of pages to parse from a text file.
'maxWords' => 1000, // Limit the number of words to parse from a text file.
'categoryGroupId' => 0,
// If true, the source EE file description and categories will be created with the AI response.
// If parseDocumentContents.enabled is true, you generally want to keep this enabled as well.
'createDescription' => true,
'createCategories' => true,
// If true, any updates to the file will fetch a new AI response and update the source EE file accordingly.
// Leave false if you want to manually manage the description and categories after it is initially created.
'replaceDescription' => false,
'replaceCategories' => false,
],
// If indexing image files (jpg, png, or gif) it will send the image to OpenAI to describe the contents
// of the file and add it to the __full_text property.
'parseImageContents' => [
'enabled' => true,
'describePrompt' => 'Describe this image in detail, including any text that may be present.',
'categoryGroupId' => 0,
// If true, the source EE file description and categories will be created with the AI response.
// If parseImageContents.enabled is true, you generally want to keep this enabled as well.
'createDescription' => true,
'createCategories' => true,
// If true, any updates to the file will fetch a new AI response and update the source EE file accordingly.
// Leave false if you want to manually manage the description and categories after it is initially created.
'replaceDescription' => false,
'replaceCategories' => false,
],
'aiProvider' => 'openAi',
'embeddingProvider' => 'openAi',
'openAi' => [
'key' => $_ENV['OPENAI_API_KEY'] ?? '',
'embedModel' => 'text-embedding-3-small',
'model' => 'gpt-4o',
'temperature' => 1.0, // The temperature of the response, 0.0 to 2.0.
'frequencyPenalty' => 0.0, // The frequency penalty of the response,
'presencePenalty' => 0.0, // The presence penalty of the response.
'maxTokens' => 300, // The maximum number of tokens to return in the response.
],
// If you are using Meilisearch, you can enable AI/vector-based searching. Using this feature requires
// includeFullText to be enabled. When content is indexed, it will use the __full_text property to generate
// embeddings/vectors for each object. This will allow you to search for similar content based on the text
// in the __full_text property. You must also include the following filter in your search queries:
// "hybrid": {
// "embedder": "fullText"
// }
// https://www.meilisearch.com/docs/learn/ai_powered_search/getting_started_with_ai_search
'enableContextSearch' => false,
// If true, Dexter will use the defined aiProvider to further filter the search results.
// This will not add additional results to the list, it will only perform an additional search filtering
// the initial results based on the query, which can take into account advanced logic such as "NOT" and "OR" operators.
// enableContextSearch must be enabled
'enableAdvancedSearch' => false,
// This is the property name that is used for the index primaryKey. In most cases the default "objectID" is sufficient.
// https://www.meilisearch.com/docs/learn/getting_started/primary_key
// If in the event you want to change the primary key name (you can set it to "entry_id" if you want), you can
// set the config value to a callable function. By default, the values of this field will be "entry_123" or "file_456",
// depending on if your indexing entries or files.
// For example:
/*
'primaryKey' => function (string $indexName, array $values) {
return ''; // do something fancy here
},
*/
'primaryKey' => 'objectID',
// Highly recommended if you are using the ?ACT endpoint to perform searches, either via an Ajax
// or server side curl request. You must pass a valid CSRF_TOKEN value along with the search request.
// An example POST body:
// {
// "index": "test_files",
// "query": "small birds",
// "csrf_token": "[token string here]",
// "filters": {
// "limit": 6,
// "hybrid": {
// "embedder": "fullText"
// }
// }
// }
'secureSearch' => true,
// Only entries with the following statuses will be indexed
'statuses' => [
'open',
],
// This is a default list of stop words that will be removed from the __full_text property.
// You can use the dexter_remove_stop_words extension hook to modify this list at runtime (ideal for multilingual sites),
// or you can set your own list of stop words in the config.
'stopWords' => [
'a', 'about', 'above', 'after', 'again', 'against', 'all', 'am', 'an', 'and', 'any', 'are',
'as', 'at', 'be', 'because', 'been', 'before', 'being', 'below', 'between', 'both', 'but',
'by', 'could', 'did', 'do', 'does', 'doing', 'down', 'during', 'each', 'few', 'for', 'from',
'further', 'had', 'has', 'have', 'having', 'he', 'her', 'here', 'hers', 'herself', 'him',
'himself', 'his', 'how', 'i', 'if', 'in', 'into', 'is', 'it', 'its', 'itself', 'let\'s',
'me', 'more', 'most', 'my', 'myself', 'nor', 'of', 'on', 'once', 'only', 'or', 'other',
'ought', 'our', 'ours', 'ourselves', 'out', 'over', 'own', 'same', 'she', 'should', 'so',
'some', 'such', 'than', 'that', 'the', 'their', 'theirs', 'them', 'themselves', 'then',
'there', 'these', 'they', 'this', 'those', 'through', 'to', 'too', 'under', 'until', 'up',
'very', 'was', 'we', 'were', 'what', 'when', 'where', 'which', 'while', 'who', 'whom',
'why', 'will', 'with', 'would', 'you', 'your', 'yours', 'yourself', 'yourselves',
],
// Highly recommended to use the Queue module if you need to batch re-index hundreds or thousands of entries.
'useQueue' => true,
];Last updated
Was this helpful?