diff --git a/database.sql b/database.sql index 5f98cd402a..9c98c614a9 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2024.03-dev (Yellow Archangel) --- DB_UPDATE_VERSION 1544 +-- DB_UPDATE_VERSION 1545 -- ------------------------------------------ @@ -504,6 +504,7 @@ CREATE TABLE IF NOT EXISTS `channel` ( `exclude-tags` varchar(1023) COMMENT 'Comma separated list of tags that aren\'t allowed in the channel', `full-text-search` varchar(1023) COMMENT 'Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode', `media-type` smallint unsigned COMMENT 'Filtered media types', + `languages` mediumtext COMMENT 'Desired languages', PRIMARY KEY(`id`), INDEX `uid` (`uid`), FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE diff --git a/doc/database/db_channel.md b/doc/database/db_channel.md index 9b9486fa32..8d307eee89 100644 --- a/doc/database/db_channel.md +++ b/doc/database/db_channel.md @@ -18,6 +18,7 @@ Fields | exclude-tags | Comma separated list of tags that aren't allowed in the channel | varchar(1023) | YES | | NULL | | | full-text-search | Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode | varchar(1023) | YES | | NULL | | | media-type | Filtered media types | smallint unsigned | YES | | NULL | | +| languages | Desired languages | mediumtext | YES | | NULL | | Indexes ------------ diff --git a/src/Content/Conversation/Entity/Timeline.php b/src/Content/Conversation/Entity/Timeline.php index 8b8a2bc064..34d2a3534a 100644 --- a/src/Content/Conversation/Entity/Timeline.php +++ b/src/Content/Conversation/Entity/Timeline.php @@ -32,6 +32,7 @@ namespace Friendica\Content\Conversation\Entity; * @property-read string $excludeTags The tags to exclude in the channel * @property-read string $fullTextSearch full text search pattern * @property-read int $mediaType Media types that are included in the channel + * @property-read array $languages Channel languages * @property-read int $circle Circle or timeline this channel is based on */ class Timeline extends \Friendica\BaseEntity @@ -58,8 +59,10 @@ class Timeline extends \Friendica\BaseEntity protected $fullTextSearch; /** @var int */ protected $mediaType; + /** @var array */ + protected $languages; - public function __construct(string $code = null, string $label = null, string $description = null, string $accessKey = null, string $path = null, int $uid = null, string $includeTags = null, string $excludeTags = null, string $fullTextSearch = null, int $mediaType = null, int $circle = null) + public function __construct(string $code = null, string $label = null, string $description = null, string $accessKey = null, string $path = null, int $uid = null, string $includeTags = null, string $excludeTags = null, string $fullTextSearch = null, int $mediaType = null, int $circle = null, array $languages = null) { $this->code = $code; $this->label = $label; @@ -72,5 +75,6 @@ class Timeline extends \Friendica\BaseEntity $this->fullTextSearch = $fullTextSearch; $this->mediaType = $mediaType; $this->circle = $circle; + $this->languages = $languages; } } diff --git a/src/Content/Conversation/Factory/UserDefinedChannel.php b/src/Content/Conversation/Factory/UserDefinedChannel.php index 43622641d3..98e10b4fbf 100644 --- a/src/Content/Conversation/Factory/UserDefinedChannel.php +++ b/src/Content/Conversation/Factory/UserDefinedChannel.php @@ -22,7 +22,6 @@ namespace Friendica\Content\Conversation\Factory; use Friendica\Capabilities\ICanCreateFromTableRow; -use Friendica\Content\Conversation\Collection\Timelines; use Friendica\Content\Conversation\Entity; final class UserDefinedChannel extends Timeline implements ICanCreateFromTableRow @@ -34,6 +33,10 @@ final class UserDefinedChannel extends Timeline implements ICanCreateFromTableRo public function createFromTableRow(array $row): Entity\UserDefinedChannel { + if (is_string($row['languages'])) { + $row['languages'] = unserialize($row['languages']); + } + return new Entity\UserDefinedChannel( $row['id'] ?? null, $row['label'], @@ -46,6 +49,7 @@ final class UserDefinedChannel extends Timeline implements ICanCreateFromTableRo $row['full-text-search'] ?? null, $row['media-type'] ?? null, $row['circle'] ?? null, + $row['languages'] ?? null, ); } } diff --git a/src/Content/Conversation/Repository/UserDefinedChannel.php b/src/Content/Conversation/Repository/UserDefinedChannel.php index e9fa365e51..7815acdd8a 100644 --- a/src/Content/Conversation/Repository/UserDefinedChannel.php +++ b/src/Content/Conversation/Repository/UserDefinedChannel.php @@ -124,6 +124,7 @@ class UserDefinedChannel extends \Friendica\BaseRepository 'exclude-tags' => $Channel->excludeTags, 'full-text-search' => $Channel->fullTextSearch, 'media-type' => $Channel->mediaType, + 'languages' => serialize($Channel->languages), ]; if ($Channel->code) { diff --git a/src/Module/Conversation/Timeline.php b/src/Module/Conversation/Timeline.php index bc4c87ce55..1fdc9e0603 100644 --- a/src/Module/Conversation/Timeline.php +++ b/src/Module/Conversation/Timeline.php @@ -312,10 +312,10 @@ class Timeline extends BaseModule } elseif ($this->selectedTab == ChannelEntity::LANGUAGE) { $condition = ["JSON_EXTRACT(JSON_KEYS(language), '$[0]') = ?", User::getLanguageCode($uid)]; } elseif (is_numeric($this->selectedTab)) { - $condition = $this->getUserChannelConditions($this->selectedTab, $this->session->getLocalUserId()); + $condition = $this->getUserChannelConditions($this->selectedTab, $uid); } - if ($this->selectedTab != ChannelEntity::LANGUAGE) { + if (($this->selectedTab != ChannelEntity::LANGUAGE) && !is_numeric($this->selectedTab)) { $condition = $this->addLanguageCondition($uid, $condition); } @@ -422,13 +422,15 @@ class Timeline extends BaseModule } // For "addLanguageCondition" to work, the condition must not be empty - return $condition ?: ["true"]; + $condition = $this->addLanguageCondition($uid, $condition ?: ["true"], $channel->languages); + + return $condition; } - private function addLanguageCondition(int $uid, array $condition): array + private function addLanguageCondition(int $uid, array $condition, $languages = null): array { $conditions = []; - $languages = User::getWantedLanguages($uid); + $languages = $languages ?: User::getWantedLanguages($uid); foreach ($languages as $language) { $conditions[] = "JSON_EXTRACT(JSON_KEYS(language), '$[0]') = ?"; $condition[] = $language; diff --git a/src/Module/Settings/Channels.php b/src/Module/Settings/Channels.php index 47074d3e09..aef8527775 100644 --- a/src/Module/Settings/Channels.php +++ b/src/Module/Settings/Channels.php @@ -28,6 +28,7 @@ use Friendica\Core\L10n; use Friendica\Core\Renderer; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Model\Circle; +use Friendica\Model\User; use Friendica\Module\BaseSettings; use Friendica\Module\Response; use Friendica\Network\HTTPException; @@ -62,7 +63,13 @@ class Channels extends BaseSettings self::checkFormSecurityTokenRedirectOnError('/settings/channels', 'settings_channels'); + $channel_languages = User::getWantedLanguages($uid); + if (!empty($request['add_channel'])) { + if (!array_diff((array)$request['new_languages'], $channel_languages)) { + $request['new_languages'] = null; + } + $channel = $this->userDefinedChannel->createFromTableRow([ 'label' => $request['new_label'], 'description' => $request['new_description'], @@ -73,6 +80,7 @@ class Channels extends BaseSettings 'exclude-tags' => $this->cleanTags($request['new_exclude_tags']), 'full-text-search' => $request['new_text_search'], 'media-type' => ($request['new_image'] ? 1 : 0) | ($request['new_video'] ? 2 : 0) | ($request['new_audio'] ? 4 : 0), + 'languages' => $request['new_languages'], ]); $saved = $this->channel->save($channel); $this->logger->debug('New channel added', ['saved' => $saved]); @@ -86,6 +94,10 @@ class Channels extends BaseSettings continue; } + if (!array_diff((array)$request['languages'][$id], $channel_languages)) { + $request['languages'][$id] = null; + } + $channel = $this->userDefinedChannel->createFromTableRow([ 'id' => $id, 'label' => $request['label'][$id], @@ -97,6 +109,7 @@ class Channels extends BaseSettings 'exclude-tags' => $this->cleanTags($request['exclude_tags'][$id]), 'full-text-search' => $request['text_search'][$id], 'media-type' => ($request['image'][$id] ? 1 : 0) | ($request['video'][$id] ? 2 : 0) | ($request['audio'][$id] ? 4 : 0), + 'languages' => $request['languages'][$id], ]); $saved = $this->channel->save($channel); $this->logger->debug('Save channel', ['id' => $id, 'saved' => $saved]); @@ -123,6 +136,9 @@ class Channels extends BaseSettings $circles[$circle['id']] = $circle['name']; } + $languages = $this->l10n->getLanguageCodes(true); + $channel_languages = User::getWantedLanguages($uid); + $channels = []; foreach ($this->channel->selectByUid($uid) as $channel) { if (!empty($request['id'])) { @@ -146,6 +162,7 @@ class Channels extends BaseSettings 'image' => ["image[$channel->code]", $this->t("Images"), $channel->mediaType & 1], 'video' => ["video[$channel->code]", $this->t("Videos"), $channel->mediaType & 2], 'audio' => ["audio[$channel->code]", $this->t("Audio"), $channel->mediaType & 4], + 'languages' => ["languages[$channel->code][]", $this->t('Languages'), $channel->languages ?? $channel_languages, $this->t('Select all languages that you want to see in this channel.'), $languages, 'multiple'], 'delete' => ["delete[$channel->code]", $this->t("Delete channel") . ' (' . $channel->label . ')', false, $this->t("Check to delete this entry from the channel list")] ]; } @@ -163,6 +180,7 @@ class Channels extends BaseSettings 'image' => ['new_image', $this->t("Images"), false, $this->t("Check to display images in the channel.")], 'video' => ["new_video", $this->t("Videos"), false, $this->t("Check to display videos in the channel.")], 'audio' => ["new_audio", $this->t("Audio"), false, $this->t("Check to display audio in the channel.")], + 'languages' => ["new_languages[]", $this->t('Languages'), $channel_languages, $this->t('Select all languages that you want to see in this channel.'), $languages, 'multiple'], '$l10n' => [ 'title' => $this->t('Channels'), 'intro' => $this->t('This page can be used to define your own channels.'), diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 4228e1a3ba..f1c4d4bda6 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -56,7 +56,7 @@ use Friendica\Database\DBA; // This file is required several times during the test in DbaDefinition which justifies this condition if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1544); + define('DB_UPDATE_VERSION', 1545); } return [ @@ -562,6 +562,7 @@ return [ "exclude-tags" => ["type" => "varchar(1023)", "comment" => "Comma separated list of tags that aren't allowed in the channel"], "full-text-search" => ["type" => "varchar(1023)", "comment" => "Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode"], "media-type" => ["type" => "smallint unsigned", "comment" => "Filtered media types"], + "languages" => ["type" => "mediumtext", "comment" => "Desired languages"], ], "indexes" => [ "PRIMARY" => ["id"], diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index b81cf81d4d..652a82709b 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2024.03-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-01-03 07:31+0000\n" +"POT-Creation-Date: 2024-01-03 19:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -66,8 +66,8 @@ msgstr "" #: src/Module/Register.php:77 src/Module/Register.php:90 #: src/Module/Register.php:206 src/Module/Register.php:245 #: src/Module/Search/Directory.php:37 src/Module/Settings/Account.php:50 -#: src/Module/Settings/Account.php:384 src/Module/Settings/Channels.php:56 -#: src/Module/Settings/Channels.php:112 src/Module/Settings/Delegation.php:90 +#: src/Module/Settings/Account.php:384 src/Module/Settings/Channels.php:57 +#: src/Module/Settings/Channels.php:125 src/Module/Settings/Delegation.php:90 #: src/Module/Settings/Display.php:90 src/Module/Settings/Display.php:197 #: src/Module/Settings/Profile/Photo/Crop.php:165 #: src/Module/Settings/Profile/Photo/Index.php:112 @@ -382,7 +382,7 @@ msgstr "" #: mod/notes.php:57 src/Content/Text/HTML.php:859 #: src/Module/Admin/Storage.php:142 src/Module/Filer/SaveTag.php:74 -#: src/Module/Post/Edit.php:129 src/Module/Settings/Channels.php:171 +#: src/Module/Post/Edit.php:129 src/Module/Settings/Channels.php:189 msgid "Save" msgstr "" @@ -794,12 +794,12 @@ msgstr "" #: src/BaseModule.php:439 src/Content/Conversation/Factory/Channel.php:45 #: src/Content/Widget.php:239 src/Core/ACL.php:195 src/Module/Contact.php:414 #: src/Module/PermissionTooltip.php:141 src/Module/PermissionTooltip.php:163 -#: src/Module/Settings/Channels.php:119 +#: src/Module/Settings/Channels.php:132 msgid "Followers" msgstr "" #: src/BaseModule.php:444 src/Content/Widget.php:240 src/Module/Contact.php:417 -#: src/Module/Settings/Channels.php:118 +#: src/Module/Settings/Channels.php:131 msgid "Following" msgstr "" @@ -1547,7 +1547,7 @@ msgid "Posts from accounts that are followed by accounts that you follow" msgstr "" #: src/Content/Conversation/Factory/Channel.php:47 -#: src/Module/Settings/Channels.php:146 src/Module/Settings/Channels.php:163 +#: src/Module/Settings/Channels.php:162 src/Module/Settings/Channels.php:180 msgid "Images" msgstr "" @@ -1556,7 +1556,7 @@ msgid "Posts with images" msgstr "" #: src/Content/Conversation/Factory/Channel.php:48 -#: src/Module/Settings/Channels.php:148 src/Module/Settings/Channels.php:165 +#: src/Module/Settings/Channels.php:164 src/Module/Settings/Channels.php:182 msgid "Audio" msgstr "" @@ -1565,7 +1565,7 @@ msgid "Posts with audio" msgstr "" #: src/Content/Conversation/Factory/Channel.php:49 -#: src/Module/Settings/Channels.php:147 src/Module/Settings/Channels.php:164 +#: src/Module/Settings/Channels.php:163 src/Module/Settings/Channels.php:181 msgid "Videos" msgstr "" @@ -1582,7 +1582,7 @@ msgid "Posts from local users on this server" msgstr "" #: src/Content/Conversation/Factory/Community.php:47 -#: src/Module/Settings/Channels.php:116 +#: src/Module/Settings/Channels.php:129 msgid "Global Community" msgstr "" @@ -1842,7 +1842,8 @@ msgstr "" msgid "Ignore %s server" msgstr "" -#: src/Content/Item.php:443 src/Object/Post.php:509 +#: src/Content/Item.php:443 src/Module/Settings/Channels.php:165 +#: src/Module/Settings/Channels.php:183 src/Object/Post.php:509 msgid "Languages" msgstr "" @@ -2045,7 +2046,7 @@ msgstr "" msgid "Terms of Service of this Friendica instance" msgstr "" -#: src/Content/Nav.php:306 src/Module/Settings/Channels.php:117 +#: src/Content/Nav.php:306 src/Module/Settings/Channels.php:130 #: view/theme/frio/theme.php:239 msgid "Network" msgstr "" @@ -2368,7 +2369,7 @@ msgid "All" msgstr "" #: src/Content/Widget.php:591 src/Module/Admin/Site.php:466 -#: src/Module/BaseSettings.php:125 src/Module/Settings/Channels.php:167 +#: src/Module/BaseSettings.php:125 src/Module/Settings/Channels.php:185 #: src/Module/Settings/Display.php:315 msgid "Channels" msgstr "" @@ -6115,7 +6116,7 @@ msgstr "" #: src/Module/Moderation/Blocklist/Server/Index.php:116 #: src/Module/Moderation/Item/Delete.php:67 src/Module/Register.php:148 #: src/Module/Security/TwoFactor/Verify.php:101 -#: src/Module/Settings/Channels.php:139 src/Module/Settings/Channels.php:156 +#: src/Module/Settings/Channels.php:155 src/Module/Settings/Channels.php:173 #: src/Module/Settings/TwoFactor/Index.php:161 #: src/Module/Settings/TwoFactor/Verify.php:158 msgid "Required" @@ -7368,7 +7369,7 @@ msgstr "" #: src/Module/Friendica.php:102 #: src/Module/Moderation/Blocklist/Server/Index.php:87 #: src/Module/Moderation/Blocklist/Server/Index.php:111 -#: src/Module/Settings/Channels.php:174 +#: src/Module/Settings/Channels.php:192 msgid "Reason for the block" msgstr "" @@ -8116,7 +8117,7 @@ msgstr "" #: src/Module/Moderation/Blocklist/Server/Index.php:86 #: src/Module/Moderation/Blocklist/Server/Index.php:110 -#: src/Module/Settings/Channels.php:173 +#: src/Module/Settings/Channels.php:191 msgid "Blocked server domain pattern" msgstr "" @@ -10104,76 +10105,80 @@ msgstr "" msgid "No Addon settings configured" msgstr "" -#: src/Module/Settings/Channels.php:139 src/Module/Settings/Channels.php:156 +#: src/Module/Settings/Channels.php:155 src/Module/Settings/Channels.php:173 #: src/Module/Settings/Display.php:338 msgid "Label" msgstr "" -#: src/Module/Settings/Channels.php:140 src/Module/Settings/Channels.php:157 +#: src/Module/Settings/Channels.php:156 src/Module/Settings/Channels.php:174 #: src/Module/Settings/Display.php:339 #: src/Module/Settings/TwoFactor/AppSpecific.php:137 msgid "Description" msgstr "" -#: src/Module/Settings/Channels.php:141 src/Module/Settings/Channels.php:158 +#: src/Module/Settings/Channels.php:157 src/Module/Settings/Channels.php:175 msgid "Access Key" msgstr "" -#: src/Module/Settings/Channels.php:142 src/Module/Settings/Channels.php:159 +#: src/Module/Settings/Channels.php:158 src/Module/Settings/Channels.php:176 msgid "Circle/Channel" msgstr "" -#: src/Module/Settings/Channels.php:143 src/Module/Settings/Channels.php:160 +#: src/Module/Settings/Channels.php:159 src/Module/Settings/Channels.php:177 msgid "Include Tags" msgstr "" -#: src/Module/Settings/Channels.php:144 src/Module/Settings/Channels.php:161 +#: src/Module/Settings/Channels.php:160 src/Module/Settings/Channels.php:178 msgid "Exclude Tags" msgstr "" -#: src/Module/Settings/Channels.php:145 src/Module/Settings/Channels.php:162 +#: src/Module/Settings/Channels.php:161 src/Module/Settings/Channels.php:179 msgid "Full Text Search" msgstr "" -#: src/Module/Settings/Channels.php:149 +#: src/Module/Settings/Channels.php:165 src/Module/Settings/Channels.php:183 +msgid "Select all languages that you want to see in this channel." +msgstr "" + +#: src/Module/Settings/Channels.php:166 msgid "Delete channel" msgstr "" -#: src/Module/Settings/Channels.php:149 +#: src/Module/Settings/Channels.php:166 msgid "Check to delete this entry from the channel list" msgstr "" -#: src/Module/Settings/Channels.php:156 +#: src/Module/Settings/Channels.php:173 msgid "Short name for the channel. It is displayed on the channels widget." msgstr "" -#: src/Module/Settings/Channels.php:157 +#: src/Module/Settings/Channels.php:174 msgid "This should describe the content of the channel in a few word." msgstr "" -#: src/Module/Settings/Channels.php:158 +#: src/Module/Settings/Channels.php:175 msgid "" "When you want to access this channel via an access key, you can define it " "here. Pay attention to not use an already used one." msgstr "" -#: src/Module/Settings/Channels.php:159 +#: src/Module/Settings/Channels.php:176 msgid "Select a circle or channel, that your channel should be based on." msgstr "" -#: src/Module/Settings/Channels.php:160 +#: src/Module/Settings/Channels.php:177 msgid "" "Comma separated list of tags. A post will be used when it contains any of " "the listed tags." msgstr "" -#: src/Module/Settings/Channels.php:161 +#: src/Module/Settings/Channels.php:178 msgid "" "Comma separated list of tags. If a post contain any of these tags, then it " "will not be part of nthis channel." msgstr "" -#: src/Module/Settings/Channels.php:162 +#: src/Module/Settings/Channels.php:179 #, php-format msgid "" "Search terms for the body, supports the \"boolean mode\" operators from " @@ -10181,39 +10186,39 @@ msgid "" "keywords: %s" msgstr "" -#: src/Module/Settings/Channels.php:163 +#: src/Module/Settings/Channels.php:180 msgid "Check to display images in the channel." msgstr "" -#: src/Module/Settings/Channels.php:164 +#: src/Module/Settings/Channels.php:181 msgid "Check to display videos in the channel." msgstr "" -#: src/Module/Settings/Channels.php:165 +#: src/Module/Settings/Channels.php:182 msgid "Check to display audio in the channel." msgstr "" -#: src/Module/Settings/Channels.php:168 +#: src/Module/Settings/Channels.php:186 msgid "This page can be used to define your own channels." msgstr "" -#: src/Module/Settings/Channels.php:169 +#: src/Module/Settings/Channels.php:187 msgid "Add new entry to the channel list" msgstr "" -#: src/Module/Settings/Channels.php:170 +#: src/Module/Settings/Channels.php:188 msgid "Add" msgstr "" -#: src/Module/Settings/Channels.php:172 +#: src/Module/Settings/Channels.php:190 msgid "Current Entries in the channel list" msgstr "" -#: src/Module/Settings/Channels.php:175 +#: src/Module/Settings/Channels.php:193 msgid "Delete entry from the channel list" msgstr "" -#: src/Module/Settings/Channels.php:176 +#: src/Module/Settings/Channels.php:194 msgid "Delete entry from the channel list?" msgstr "" diff --git a/view/templates/settings/channels.tpl b/view/templates/settings/channels.tpl index 27defffdb0..3b84741425 100644 --- a/view/templates/settings/channels.tpl +++ b/view/templates/settings/channels.tpl @@ -14,6 +14,7 @@ {{include file="field_checkbox.tpl" field=$image}} {{include file="field_checkbox.tpl" field=$video}} {{include file="field_checkbox.tpl" field=$audio}} + {{include file="field_select.tpl" field=$languages}}
@@ -34,6 +35,7 @@ {{include file="field_checkbox.tpl" field=$e.image}} {{include file="field_checkbox.tpl" field=$e.video}} {{include file="field_checkbox.tpl" field=$e.audio}} + {{include file="field_select.tpl" field=$e.languages}} {{include file="field_checkbox.tpl" field=$e.delete}}
{{/foreach}} diff --git a/view/theme/frio/templates/settings/channels.tpl b/view/theme/frio/templates/settings/channels.tpl index 7ed2b1cc5d..6761127957 100644 --- a/view/theme/frio/templates/settings/channels.tpl +++ b/view/theme/frio/templates/settings/channels.tpl @@ -22,6 +22,7 @@ {{include file="field_checkbox.tpl" field=$image}} {{include file="field_checkbox.tpl" field=$video}} {{include file="field_checkbox.tpl" field=$audio}} + {{include file="field_select.tpl" field=$languages}}
@@ -51,6 +52,7 @@ {{include file="field_checkbox.tpl" field=$e.image}} {{include file="field_checkbox.tpl" field=$e.video}} {{include file="field_checkbox.tpl" field=$e.audio}} + {{include file="field_select.tpl" field=$e.languages}} {{include file="field_checkbox.tpl" field=$e.delete}}