+ <%= link_to "#{Discourse.base_url}/t/#{@tag_id}", itemprop: 'item' do %>
+ <%= @tag_id %>
+ <% end %>
+
+<% end %>
+
<% if @category %>
<% if @category.parent_category %>
diff --git a/app/views/topics/show.html.erb b/app/views/topics/show.html.erb
index 010999cc9..b227aa3c6 100644
--- a/app/views/topics/show.html.erb
+++ b/app/views/topics/show.html.erb
@@ -17,7 +17,19 @@
<% end %>
<% end %>
+
+<%- if SiteSetting.tagging_enabled && @topic_view.topic.tags.present? %>
+
+ <%= t 'js.tagging.tags' %>:
+
+ <%- @topic_view.topic.tags.each do |t| %>
+ <%= t %>
+ <%- end %>
+
+<% end %>
+
<%= server_plugin_outlet "topic_header" %>
+
<%- if include_crawler_content? %>
diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml
index 6a9f585a8..2bf819fd0 100644
--- a/config/locales/client.de.yml
+++ b/config/locales/client.de.yml
@@ -1052,6 +1052,9 @@ de:
selected:
one: "Du hast ein Thema ausgewählt."
other: "Du hast {{count}} Themen ausgewählt."
+ change_tags: "Tags ändern"
+ choose_new_tags: "Wähle neue Tags für diese Themen:"
+ changed_tags: "Die Tags dieser Themen wurden geändert."
none:
unread: "Du hast alle Themen gelesen."
new: "Es gibt für dich keine neuen Themen."
@@ -2204,6 +2207,8 @@ de:
grant_moderation: "Moderation gewähren"
revoke_moderation: "Moderation entziehen"
backup_operation: "Backup läuft"
+ deleted_tag: "Tag löschen"
+ renamed_tag: "Tag umbenennen"
screened_emails:
title: "Gefilterte E-Mails"
description: "Wenn jemand ein Konto erstellt, werden die folgenden E-Mail-Adressen überprüft und es wird die Anmeldung blockiert oder eine andere Aktion ausgeführt."
@@ -2699,3 +2704,32 @@ de:
+
+ tagging:
+ all_tags: "Alle Tags"
+ selector_all_tags: "Alle Tags"
+ changed: "Tags geändert:"
+ tags: "Tags"
+ choose_for_topic: "Wähle optional Tags für dieses Thema"
+ topics_tagged: "Themen getaggt mit {{tag}}"
+ delete_tag: "Tag löschen"
+ delete_confirm: "Bist du sicher, dass du das Tag löschen möchtest?"
+ rename_tag: "Tag umbenennen"
+ rename_instructions: "Wähle einen neuen Namen für das Tag:"
+ sort_by: "Sortieren nach:"
+ sort_by_count: "Anzahl"
+ sort_by_name: "Name"
+
+ notifications:
+ watching:
+ title: "Beobachten"
+ description: "Du wirst automatisch alle neuen Themen dieses Tags beobachten. Du wirst über jeden neuen Beitrag und jedes neue Thema benachrichtigt. Die Anzahl der ungelesenen und neuen Beiträge wird neben dem Thema erscheinen."
+ tracking:
+ title: "Verfolgen"
+ description: "Du wirst automatisch alle neuen Themen dieses Tags verfolgen. Die Anzahl der ungelesenen und neuen Beiträge wird neben dem Thema erscheinen."
+ regular:
+ title: "Normal"
+ description: "Du wirst benachrichtigt, wenn jemand deinen @Namen erwähnt oder auf deinen Beitrag antwortet."
+ muted:
+ title: "Stummgeschaltet"
+ description: "Du erhältst keine Benachrichtigungen über neue Themen mit diesem Tag und es wird nicht in deiner Liste ungelesener Tags erscheinen."
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 482b17ee3..506989e43 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1164,6 +1164,9 @@ en:
selected:
one: "You have selected 1 topic."
other: "You have selected {{count}} topics."
+ change_tags: "Change Tags"
+ choose_new_tags: "Choose new tags for these topics:"
+ changed_tags: "The tags of those topics were changed."
none:
unread: "You have no unread topics."
@@ -2410,6 +2413,8 @@ en:
grant_moderation: "grant moderation"
revoke_moderation: "revoke moderation"
backup_operation: "backup operation"
+ deleted_tag: "deleted tag"
+ renamed_tag: "renamed tag"
screened_emails:
title: "Screened Emails"
description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed."
@@ -2704,6 +2709,7 @@ en:
login: "Login"
plugins: "Plugins"
user_preferences: "User Preferences"
+ tags: "Tags"
badges:
title: Badges
@@ -2922,3 +2928,58 @@ en:
+
+ tagging:
+ all_tags: "All Tags"
+ selector_all_tags: "all tags"
+ changed: "tags changed:"
+ tags: "Tags"
+ choose_for_topic: "choose optional tags for this topic"
+ delete_tag: "Delete Tag"
+ delete_confirm: "Are you sure you want to delete that tag?"
+ rename_tag: "Rename Tag"
+ rename_instructions: "Choose a new name for the tag:"
+ sort_by: "Sort by:"
+ sort_by_count: "count"
+ sort_by_name: "name"
+
+ filters:
+ without_category: "%{filter} %{tag} topics"
+ with_category: "%{filter} %{tag} topics in %{category}"
+
+ notifications:
+ watching:
+ title: "Watching"
+ description: "You will automatically watch all new topics in this tag. You will be notified of all new posts and topics, plus the count of unread and new posts will also appear next to the topic."
+ tracking:
+ title: "Tracking"
+ description: "You will automatically track all new topics in this tag. A count of unread and new posts will appear next to the topic."
+ regular:
+ title: "Regular"
+ description: "You will be notified if someone mentions your @name or replies to your post."
+ muted:
+ title: "Muted"
+ description: "You will not be notified of anything about new topics in this tag, and they will not appear on your unread tab."
+
+ topics:
+ none:
+ unread: "You have no unread topics."
+ new: "You have no new topics."
+ read: "You haven't read any topics yet."
+ posted: "You haven't posted in any topics yet."
+ latest: "There are no latest topics."
+ hot: "There are no hot topics."
+ bookmarks: "You have no bookmarked topics yet."
+ top: "There are no top topics."
+ search: "There are no search results."
+ bottom:
+ latest: "There are no more latest topics."
+ hot: "There are no more hot topics."
+ posted: "There are no more posted topics."
+ read: "There are no more read topics."
+ new: "There are no more new topics."
+ unread: "There are no more unread topics."
+ top: "There are no more top topics."
+ bookmarks: "There are no more bookmarked topics."
+ search: "There are no more search results."
+
diff --git a/config/locales/client.es.yml b/config/locales/client.es.yml
index 09aa1e8f1..dedf5e6ff 100644
--- a/config/locales/client.es.yml
+++ b/config/locales/client.es.yml
@@ -1052,6 +1052,9 @@ es:
selected:
one: "Has seleccionado 1 tema."
other: "Has seleccionado {{count}} temas."
+ change_tags: "Cambiar etiquetas"
+ choose_new_tags: "Elegir nuevas etiquetas para estos temas:"
+ changed_tags: "Las etiquetas de estos temas fueron cambiadas."
none:
unread: "No hay temas que sigas y que no hayas leído ya."
new: "No tienes temas nuevos por leer."
@@ -2208,6 +2211,8 @@ es:
grant_moderation: "conceder moderación"
revoke_moderation: "revocar moderación"
backup_operation: "operación de copia de seguridad de respaldo"
+ deleted_tag: "etiqueta eliminada"
+ renamed_tag: "etiqueta renombrada"
screened_emails:
title: "Correos bloqueados"
description: "Cuando alguien trata de crear una cuenta nueva, los siguientes correos serán revisados y el registro será bloqueado, o alguna otra acción será realizada."
@@ -2703,3 +2708,54 @@ es:
+
+ tagging:
+ all_tags: "Etiquetas"
+ selector_all_tags: "etiquetas"
+ changed: "etiquetas cambiadas:"
+ tags: "Etiquetas"
+ choose_for_topic: "elegir etiquetas para este tema (opcional)"
+ delete_tag: "Eliminar etiqueta"
+ delete_confirm: "¿Seguro que quieres eliminar esta etiqueta?"
+ rename_tag: "Renombrar etiqueta"
+ rename_instructions: "Elige un nuevo nombre para la etiqueta:"
+ sort_by: "Ordenar por:"
+ sort_by_count: "volumen"
+ sort_by_name: "nombre"
+
+ notifications:
+ watching:
+ title: "Vigilar"
+ description: "Vigilarás automáticamente todos los nuevos temas con esta etiqueta. Se añadirá un contador de posts nuevos y sin leer al lado del tema y además, se te notificará de cada nuevo tema y post."
+ tracking:
+ title: "Seguir"
+ description: "Seguirás automáticamente todos los nuevos temas con esta etiqueta. Se añadirá un contador de posts nuevos y sin leer al lado del tema."
+ regular:
+ title: "Normal"
+ description: "Se te notificará solo si alguien te menciona con tu @usuario o responde a algún post tuyo."
+ muted:
+ title: "Silenciar"
+ description: "No se te notificará de nuevos temas con esta etiqueta, ni aparecerán en tu pestaña de temas no leídos."
+
+ topics:
+ none:
+ unread: "No tienes temas sin leer."
+ new: "No hay temas nuevos."
+ read: "Aún no has leído ningún tema."
+ posted: "Aún no has publicado en ningún tema."
+ latest: "No hay temas recientes."
+ hot: "No hay temas candentes"
+ bookmarks: "Aún no has guardado temas en marcadores."
+ top: "No hay temas top."
+ search: "No hay resultados resultados de búsqueda."
+ bottom:
+ latest: "No hay más temas recientes."
+ hot: "No hay más temas candentes."
+ posted: "No hay más temas en los que hayas publicado."
+ read: "No hay más temas que hayas leído."
+ new: "No hay más temas nuevos."
+ unread: "No hay más temas sin leer."
+ top: "No hay más temas top."
+ bookmarks: "No hay más temas en marcadores."
+ search: "No hay más resultados de búsqueda."
+
diff --git a/config/locales/client.fa_IR.yml b/config/locales/client.fa_IR.yml
index 048a86b1e..4706ddeb4 100644
--- a/config/locales/client.fa_IR.yml
+++ b/config/locales/client.fa_IR.yml
@@ -918,6 +918,9 @@ fa_IR:
choose_new_category: "یک دسته بندی جدید برای موضوع انتخاب نمایید"
selected:
other: "شما تعداد {{count}} موضوع را انتخاب کرده اید."
+ change_tags: "تغییر برچسب ها"
+ choose_new_tags: "انتخاب برچسب های جدید برای این موضوع:"
+ changed_tags: "برچسب های انتخابی برای این موضوع جایگزین شد."
none:
unread: "موضوع خوانده نشدهای ندارید."
new: "شما هیچ موضوع تازهای ندارید"
@@ -1956,6 +1959,8 @@ fa_IR:
change_category_settings: "تغییر تنظیمات دسته بندی"
delete_category: "حذف دسته بندی"
create_category: "ساخت دسته بندی"
+ deleted_tag: "حذف برچسب"
+ renamed_tag: "تغییر نام برچسب"
screened_emails:
title: "ایمیل ها نمایش داده شده"
description: "وقتی کسی سعی می کند یک حساب جدید ایجاد کند، از آدرس ایمیل زیر بررسی و ثبت نام مسدود خواهد شد، و یا برخی از اقدام های دیگر انجام می شود."
@@ -2430,3 +2435,27 @@ fa_IR:
+ tagging:
+ all_tags: "تمام پرچسب ها"
+ changed: "برچسب های تغییر یافته:"
+ tags: "برچسب ها"
+ choose_for_topic: "انتخاب برچسب اختیاری برای این موضوع"
+ delete_tag: "حذف برچسب"
+ delete_confirm: "آیا مطمئنید که می خواهید این برچسب را خذف کنید?"
+ rename_tag: "تغییر نام برچسب"
+ rename_instructions: "یک نام جدید برای برچسب انتخاب نمایید:"
+
+ notifications:
+ watching:
+ title: "تماشا"
+ description: "شما به صورت خودکار تمام نوشته های این برچسب را مشاهده خواهید کرد، تمام نوشته ها به شما اطلاع رسانی خواهد شد.و تعداد نوشته های خوانده نشده در جلوی موضوعات نشان داده خواهد شد."
+ tracking:
+ title: "پی گیری"
+ description: "شما به صورت خودکار تمام نوشته های این برچسب را پی گیری خواهید کرد، تمام نوشته های خوانده نشده جلوی موضوعات نشان داده خواهد شد."
+ regular:
+ title: "منظم"
+ description: "به شما اطلاع داده خواهد شد اگر کسی به شما اششاره@name یا به نوشته شما پاسخ دهند."
+ muted:
+ title: "بی صدا"
+ description: "به شما هیچ چیزی در باره نوشته های این تگ اطلاع رسانی نخواهد شد."
+
diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml
index ad45574ec..213604886 100644
--- a/config/locales/client.fi.yml
+++ b/config/locales/client.fi.yml
@@ -1019,6 +1019,9 @@ fi:
selected:
one: "Olet valinnut yhden ketjun."
other: "Olet valinnut {{count}} ketjua."
+ change_tags: "Muuta tagit"
+ choose_new_tags: "Valitse uudet tagit näille aiheille:"
+ changed_tags: "Aiheiden tagit on vaihdettu."
none:
unread: "Sinulla ei ole lukemattomia ketjuja."
new: "Sinulla ei ole uusia ketjuja."
@@ -2166,6 +2169,8 @@ fi:
grant_moderation: "myönnä valvojan oikeudet"
revoke_moderation: "peru valvojan oikeudet"
backup_operation: "varmuuskopiointi"
+ deleted_tag: "poistettu tagi"
+ renamed_tag: "uudelleennimetty tagi"
screened_emails:
title: "Seulottavat sähköpostiosoitteet"
description: "Uuden käyttäjätunnuksen luonnin yhteydessä annettua sähköpostiosoitetta verrataan alla olevaan listaan ja tarvittaessa tunnuksen luonti joko estetään tai suoritetaan muita toimenpiteitä."
@@ -2656,3 +2661,27 @@ fi:
+ tagging:
+ all_tags: "Kaikki tagit"
+ changed: "muutetut tagit:"
+ tags: "Tagit"
+ choose_for_topic: "valitse sopivat tagit aiheelle"
+ topics_tagged: "Aiheet tagattu {{tag}}"
+ delete_tag: "Poista tagi"
+ delete_confirm: "Haluatko varmasti poistaa tagin?"
+ rename_tag: "Uudelleennimeä tagi"
+ rename_instructions: "Valitse tagin uusi nimi:"
+
+ notifications:
+ watching:
+ title: "Tarkkaile"
+ description: "Saat ilmoituksen kaikista uusista viesteistä ja ketjuista jotka käyttää tätä tagia. Uusien ja lukemattomien määrä näkyy ketjun yhteydessä."
+ tracking:
+ title: "Seuraa"
+ description: "Seuraat automaattisesti tämän tagin ketjuja ja viestejä. Uusien ja lukemattomien määrä näkyy ketjun yhteydessä."
+ regular:
+ title: "Tavallinen"
+ description: "Saat ilmoituksen kun joku mainitsee @nimesi tai vastaa ketjuun."
+ muted:
+ title: "Vaimenna"
+ description: "Et saa ilmoituksia, eikä se näy lukemattomissa."
diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml
index e46cd3dfb..1483e4038 100644
--- a/config/locales/client.fr.yml
+++ b/config/locales/client.fr.yml
@@ -1018,6 +1018,9 @@ fr:
selected:
one: "Vous avez sélectionné 1 sujet."
other: "Vous avez sélectionné {{count}} sujets."
+ change_tags: "Modifier les tags"
+ choose_new_tags: "Choisir de nouveaux tags pour ces sujets :"
+ changed_tags: "Les tags de ces sujets ont été modifiés."
none:
unread: "Vous n'avez aucun sujet non lu."
new: "Vous n'avez aucun nouveau sujet."
@@ -2164,6 +2167,8 @@ fr:
grant_moderation: "Accorder les droits de modération"
revoke_moderation: "Révoquer les droits de modération"
backup_operation: "sauvegarde"
+ deleted_tag: "tag supprimé"
+ renamed_tag: "tag renommé"
screened_emails:
title: "Courriels affichés"
description: "Lorsque quelqu'un essaye de créé un nouveau compte, les adresses de courriel suivantes seront vérifiées et l'inscription sera bloquée, ou une autre action sera réalisée."
@@ -2649,3 +2654,26 @@ fr:
+ tagging:
+ all_tags: "Tous les tags"
+ changed: "tags modifiés:"
+ tags: "Tags"
+ choose_for_topic: "choisissez des tags pour ce sujet (optionnel)"
+ delete_tag: "Supprimer ce tag"
+ delete_confirm: "Êtes-vous sûr de vouloir supprimer ce tag ?"
+ rename_tag: "Renommer ce tag"
+ rename_instructions: "Choisissez un nouveau nom pour le tag :"
+
+ notifications:
+ watching:
+ title: "Surveiller"
+ description: "Vous surveillerez automatiquement les nouveaux sujets portant ce tag. Vous serez averti de tous les nouveaux messages et sujets. De plus, le nombre de messages non lus et nouveaux apparaîtra en regard du sujet."
+ tracking:
+ title: "Suivre"
+ description: "Vous suivrez automatiquement les nouveaux sujets portant ce tag. Le nombre de messages non lus et nouveaux apparaîtra en regard du sujet."
+ regular:
+ title: "Normal"
+ description: "Vous serez averti si quelqu'un mentionne votre @pseudo ou répond à votre message."
+ muted:
+ title: "Silencieux"
+ description: "Vous ne recevrez aucune notification des sujets portant ce tag, et ils n'apparaîtront pas dans votre onglet non lus."
diff --git a/config/locales/client.nb_NO.yml b/config/locales/client.nb_NO.yml
index 36e38590e..452b8630e 100644
--- a/config/locales/client.nb_NO.yml
+++ b/config/locales/client.nb_NO.yml
@@ -899,6 +899,9 @@ nb_NO:
selected:
one: "Du har valgt 1 emne."
other: "Du har valgt {{count}} emner."
+ change_tags: "Endre emneord"
+ choose_new_tags: "Velg nye emneord for disse emnene:"
+ changed_tags: "Emneord for disse emnene ble endret."
none:
unread: "Du har ingen uleste emner å lese."
new: "Du har ingen nye emner å lese."
@@ -1950,6 +1953,8 @@ nb_NO:
roll_up: "rull opp IP-blokker"
delete_category: "slett kategori"
create_category: "opprett kategori"
+ deleted_tag: "Slettet emneord"
+ renamed_tag: "Endret emneord"
screened_emails:
title: "Kontrollerte e-poster"
description: "Når noen forsøker å lage en ny konto, vil de følgende e-postadressene bli sjekket, og registreringen vil bli blokkert, eller en annen handling vil bli utført."
@@ -2374,3 +2379,27 @@ nb_NO:
name: Annet
posting:
name: Posting
+ tagging:
+ all_tags: "Alle emneord"
+ changed: "emneord endret:"
+ tags: "Emneord"
+ choose_for_topic: "velg ekstra emneord for dette emnet"
+ delete_tag: "Slett emneord"
+ delete_confirm: "Er du sikker påat du ønsker å slette dette emneordet?"
+ rename_tag: "Endre emneord"
+ rename_instructions: "Velg et nytt navn på dette emneordet:"
+
+ notifications:
+ watching:
+ title: "Følger"
+ description: "Du vil automatisk følge alle nye emner med dette emneordet. Du vil bli varslet om alle nye innlegg og emner samt at antallet uleste og nye innlegg vil vises sammen med emneoppføringen."
+ tracking:
+ title: "Følger"
+ description: "Du vil automatisk følge alle nye emner med dette emneordet. Antallet uleste og nye innlegg vil vises sammen med emneoppføringen."
+ regular:
+ title: "Vanlig"
+ description: "Du vil bli varslet om noen nevnet ditt @navn eller svarer på din post."
+ muted:
+ title: "Dempet"
+ description: "Du vil ikke bli varslet om noe vedrørende disse emneneordene og de vil ikke vises i din ulest-liste."
+
diff --git a/config/locales/client.pl_PL.yml b/config/locales/client.pl_PL.yml
index 51327dcd4..ee67063e4 100644
--- a/config/locales/client.pl_PL.yml
+++ b/config/locales/client.pl_PL.yml
@@ -2699,3 +2699,9 @@ pl_PL:
+ tagging:
+ all_tags: "Wszystkie tagi"
+ changed: "zmienione tagi:"
+ tags: "Tagi"
+ choose_for_topic: "wybierz opcjonalne tagi dla tego tematu"
+ topics_tagged: "Tematy otagowane jako {{tag}}"
diff --git a/config/locales/client.pt.yml b/config/locales/client.pt.yml
index 964b58e17..ed2dba1d6 100644
--- a/config/locales/client.pt.yml
+++ b/config/locales/client.pt.yml
@@ -1052,6 +1052,9 @@ pt:
selected:
one: "Selecionou 1 tópico."
other: "Selecionou {{count}} tópicos."
+ change_tags: "Alterar etiquetas"
+ choose_new_tags: "Escolher novas etiquetas para estes tópicos:"
+ changed_tags: "As etiquetas desses tópicos foram alteradas."
none:
unread: "Tem tópicos não lidos."
new: "Não tem novos tópicos."
@@ -2208,6 +2211,8 @@ pt:
grant_moderation: "conceder moderação"
revoke_moderation: "revogar moderação"
backup_operation: "operação de cópia de segurança"
+ deleted_tag: "etiqueta apagada"
+ renamed_tag: "etiqueta renomeada"
screened_emails:
title: "Emails Filtrados"
description: "Quando alguém tenta criar uma nova conta, os seguintes endereços de email serão verificados e o registo será bloqueado, ou outra ação será executada."
@@ -2703,3 +2708,25 @@ pt:
+ tagging:
+ all_tags: "Todas as etiquetas"
+ changed: "etiquetas alteradas:"
+ tags: "Etiquetas"
+ choose_for_topic: "escolher etiqetas opcionais para este tópico"
+ delete_tag: "Apagar etiqueta"
+ delete_confirm: "Tem a certeza que quer apagar esta etiqueta?"
+ rename_tag: "Renomear Etiqueta"
+ rename_instructions: "Escolher um novo nome para a etiqueta:"
+ notifications:
+ watching:
+ title: "A vigiar"
+ description: "Irá automaticamente vigiar todos os novos tópicos com esta etiqueta. Será notoficado de todas as novas mensagens e tópicos."
+ tracking:
+ title: "A acompanhar"
+ description: "Irá automaticamente acompanhar todos os novos tópcicos com esta etiqueta"
+ regular:
+ title: "Habitual"
+ description: "Será notoficado se mencionarem o seu @nome ou se alguém lhe responder"
+ muted:
+ title: "Silenciado"
+ description: "Não será notoficado sobre nenhum tópico com esta etiqueta"
diff --git a/config/locales/client.pt_BR.yml b/config/locales/client.pt_BR.yml
index 55ddb7114..b6ddc76de 100644
--- a/config/locales/client.pt_BR.yml
+++ b/config/locales/client.pt_BR.yml
@@ -1049,6 +1049,9 @@ pt_BR:
selected:
one: "Você selecionou 1 tópico."
other: "Você selecionou {{count}} tópicos."
+ change_tags: "Alterar Tags"
+ choose_new_tags: "Escolha novas tags para estes tópicos:"
+ changed_tags: "As tags desses tópicos foram alteradas."
none:
unread: "Não há nenhum tópico não lido."
new: "Não há tópicos novos."
@@ -2148,6 +2151,8 @@ pt_BR:
block_user: "bloquear usuário"
unblock_user: "desbloquear usuário"
backup_operation: "operação de backup"
+ deleted_tag: "tag removida"
+ renamed_tag: "tag renomeada"
screened_emails:
title: "Emails Filtrados"
description: "Quando alguém tenta cria uma nova conta, os seguintes endereços de email serão verificados e o registro será bloqueado, ou outra ação será executada."
@@ -2628,3 +2633,52 @@ pt_BR:
+ tagging:
+ all_tags: "Todas as Tags"
+ selector_all_tags: "todas as tags"
+ changed: "tags alteradas:"
+ tags: "Tags"
+ choose_for_topic: "escolha tags opcionais para este tópico"
+ delete_tag: "Remover Tag"
+ delete_confirm: "Você tem certeza que quer remover essa tag?"
+ rename_tag: "Renomear Tag"
+ rename_instructions: "Escolha um novo nome para a tag:"
+ sort_by: "Ordenar por:"
+ sort_by_count: "número"
+ sort_by_name: "nome"
+
+ notifications:
+ watching:
+ title: "Observando"
+ description: "Você vai observar automaticamente todos os novos tópicos dessa tag. Você será notificado de todas as novas mensagens e tópicos, e uma contagem de novas respostas será mostrada ao lado do tópico."
+ tracking:
+ title: "Monitorando"
+ description: "Você vai monitorar automaticamente todos os novos tópicos dessa tag. Uma contagem de novas respostas será mostrada ao lado do tópico."
+ regular:
+ title: "Normal"
+ description: "Você será notificado se alguém mencionar o seu @nome ou responder à sua mensagem."
+ muted:
+ title: "Silenciado"
+ description: "Você nunca será notificado sobre novos tópicos nessa tag, e eles não aparecerão na sua aba não lidas."
+
+ topics:
+ none:
+ unread: "Você não possui tópicos não lidos."
+ new: "Você não possui novos tópicos."
+ read: "Você não leu nenhum tópico ainda."
+ posted: "Você não postou em nenhum tópico ainda."
+ latest: "Não há tópicos mais recentes."
+ hot: "Não há tópicos quentes."
+ bookmarks: "Você não possui tópicos favoritos ainda."
+ top: "Não há melhores tópicos."
+ search: "Nenhum resultado encontrado."
+ bottom:
+ latest: "Não há mais tópicos mais recentes."
+ hot: "Não há mais tópicos quentes."
+ posted: "Não há mais tópicos postados."
+ read: "Não há mais tópicos lidos."
+ new: "Não há mais tópicos novos."
+ unread: "Não há mais tópicos não lidos."
+ top: "Não há mais melhores tópicos."
+ bookmarks: "Não há mais tópicos favoritos."
+ search: "Não há mais resultados de busca."
diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml
index c80200f50..42180d736 100644
--- a/config/locales/client.ru.yml
+++ b/config/locales/client.ru.yml
@@ -1098,6 +1098,9 @@ ru:
few: "Вы выбрали {{count}} темы."
many: "Вы выбрали {{count}} тем."
other: "Вы выбрали {{count}} тем."
+ change_tags: "Изменить теги"
+ choose_new_tags: "Выберите новые теги для этих тем:"
+ changed_tags: "Теги изменены."
none:
unread: "У вас нет непрочитанных тем."
new: "У вас нет новых тем."
@@ -2303,6 +2306,8 @@ ru:
revoke_admin: "отозваны права администратора"
grant_moderation: "выданы права модератора"
revoke_moderation: "отозваны права модератора"
+ deleted_tag: "удалить тег"
+ renamed_tag: "переименовать тег"
screened_emails:
title: "Почтовые адреса"
description: "Когда кто-то создает новую учетную запись, проверяется данный почтовый адрес и регистрация блокируется или производятся другие дополнительные действия."
@@ -2793,3 +2798,30 @@ ru:
+ tagging:
+ all_tags: "Все теги"
+ selector_all_tags: "все теги"
+ changed: "теги изменены:"
+ tags: "Теги"
+ choose_for_topic: "выберите теги для темы"
+ delete_tag: "Удалить тег"
+ delete_confirm: "Удалить тег?"
+ rename_tag: "Переименовать тег"
+ rename_instructions: "Выберите новое имя для тега:"
+ sort_by: "Сортировать по:"
+ sort_by_count: "количеству"
+ sort_by_name: "имени"
+
+ notifications:
+ watching:
+ title: "Наблюдать"
+ description: "Уведомлять о каждой новой теме с этим тегом и показывать счетчик новых непрочитанных ответов."
+ tracking:
+ title: "Следить"
+ description: "Количество непрочитанных сообщений появится рядом с названием новых тем с этим тегом."
+ regular:
+ title: "Уведомлять"
+ description: "Вам придет уведомление, только если кто-нибудь упомянет ваш @псевдоним или ответит на ваше сообщение."
+ muted:
+ title: "Без уведомлений"
+ description: "Не уведомлять об изменениях в новых темах с этим тегом и скрыть их из непрочитанных."
diff --git a/config/locales/client.tr_TR.yml b/config/locales/client.tr_TR.yml
index 153ab3ef0..85c88db7f 100644
--- a/config/locales/client.tr_TR.yml
+++ b/config/locales/client.tr_TR.yml
@@ -991,6 +991,9 @@ tr_TR:
choose_new_category: "Konular için yeni bir kategori seçin:"
selected:
other: "{{count}} konu seçtiniz."
+ change_tags: "Etiketleri değiştir"
+ choose_new_tags: "Bu konular için yeni etiket seç:"
+ changed_tags: "Seçtğiniz konular için etiketler değiştirildi."
none:
unread: "Okunmamış konunuz yok."
new: "Yeni konunuz yok."
@@ -2081,6 +2084,8 @@ tr_TR:
grant_moderation: "moderasyon yetkisi ver"
revoke_moderation: "moderasyon yetkisini kaldır"
backup_operation: "yedek operasyonu"
+ deleted_tag: "silinmiş etiket"
+ renamed_tag: "yeniden adlandırılmış etiket"
screened_emails:
title: "Taranmış E-postalar"
description: "Biri yeni bir hesap oluşturmaya çalıştığında, aşağıdaki e-posta adresleri kontrol edilecek ve kayıt önlenecek veya başka bir aksiyon alınacak."
@@ -2557,3 +2562,26 @@ tr_TR:
+ tagging:
+ all_tags: "Tüm etiketler"
+ changed: "Etiketler değişti:"
+ tags: "Etiketler"
+ choose_for_topic: "Bu konu için opsiyonel olarak bir etiket seçin"
+ delete_tag: "Etiketi sil"
+ delete_confirm: "Bu etiketi kaldırmak istediğinize emin misiniz?"
+ rename_tag: "Etiketi yeniden adlandır"
+ rename_instructions: "Etiket için yeni bir ad girin:"
+
+ notifications:
+ watching:
+ title: "Gözleniyor"
+ description: "Bu etikette ki her yeni gönderi için bir bildirim alacaksınız. Okunmamış ve yeni gönderilerin sayısı konunun yanında belirecek."
+ tracking:
+ title: "Takip Ediliyor"
+ description: "Bu etikette ki her yeni gönderi takip edilecek. Okunmamış ve yeni gönderilerin sayısı konunun yanında belirecek."
+ regular:
+ title: "Standart"
+ description: "Biri @isim şeklinde sizden bahsederse ya da gönderinize cevap verirse bildirim alacaksınız."
+ muted:
+ title: "Susturuldu"
+ description: "Bu etiket okunmamışlar sekmenizde belirmeyecek, ve hakkında hiç bir bildirim almayacaksınız."
diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml
index 66e9c06c6..d5f127fe0 100644
--- a/config/locales/client.zh_CN.yml
+++ b/config/locales/client.zh_CN.yml
@@ -1005,6 +1005,9 @@ zh_CN:
choose_new_category: "为主题选择新分类:"
selected:
other: "你已经选择了 {{count}}个主题"
+ change_tags: "更改标签"
+ choose_new_tags: "为这些主题选择新标签:"
+ changed_tags: "这些主题的标签已被修改。"
none:
unread: "你没有未读主题。"
new: "你没有新主题可读。"
@@ -2100,6 +2103,8 @@ zh_CN:
grant_moderation: "授予版主权限"
revoke_moderation: "撤销版主权限"
backup_operation: "备份操作"
+ deleted_tag: "deleted tag"
+ renamed_tag: "renamed tag"
screened_emails:
title: "被屏蔽的邮件地址"
description: "当有人试图用以下邮件地址注册时,将受到阻止或其它系统操作。"
@@ -2578,3 +2583,52 @@ zh_CN:
+ tagging:
+ all_tags: "全部标签"
+ selector_all_tags: "所有标签"
+ changed: "标签更改:"
+ tags: "标签"
+ choose_for_topic: "为主题选择可选标签"
+ delete_tag: "删除标签"
+ delete_confirm: "你确定要删除该标签?"
+ rename_tag: "重命名标签"
+ rename_instructions: "为标签选择一个新的名字:"
+ sort_by: "排列顺序:"
+ sort_by_count: "数量"
+ sort_by_name: "名字"
+
+ notifications:
+ watching:
+ title: "关注"
+ description: "你能自动关注该标签下的所有主题。一旦与这个标签有关的新主题和新帖子发表,你都会收到通知。未读贴和新帖子的数量将出现在主题列表中每个主题的标题后。"
+ tracking:
+ title: "追踪"
+ description: "你能自动追踪这个标签下的所有新主题。未读贴和新帖子的数量将出现在主题列表中每个主题的标题后。"
+ regular:
+ title: "常规"
+ description: "当有人@你或者回复你的帖子时,你才会收到通知。"
+ muted:
+ title: "防打扰"
+ description: "你不会收到该标签下的新主题的任何通知,也不会在你的未阅选项卡中显示。"
+
+ topics:
+ none:
+ unread: "你没有未读主题。"
+ new: "你没有近期主题。"
+ read: "你还未阅读任何主题。"
+ posted: "你还未在任何主题中回复。"
+ latest: "没有最新主题。"
+ hot: "没有热门主题。"
+ bookmarks: "你还没有加上书签的主题。"
+ top: "没有热门主题。"
+ search: "搜索无结果。"
+ bottom:
+ latest: "没有更多最新主题了。"
+ hot: "没有更多热门主题了。"
+ posted: "没有更多发表的主题了。"
+ read: "没有更多读过的主题了。"
+ new: "没有更多近期主题了。"
+ unread: "没有更多未读主题了。"
+ top: "没有更多热门主题了。"
+ bookmarks: "没有更多加上书签的主题了。"
+ search: "没有更多搜索结果了。"
diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml
index ba044fc61..baf013524 100644
--- a/config/locales/server.de.yml
+++ b/config/locales/server.de.yml
@@ -1101,6 +1101,19 @@ de:
default_categories_watching: "Liste der standardmäßig beobachteten Kategorien."
default_categories_tracking: "Liste der standardmäßig gefolgten Kategorien."
default_categories_muted: "Liste der standardmäßig stummgeschalteten Kategorien."
+ tagging_enabled: "Nutzern erlauben Themen zu taggen?"
+ min_trust_to_create_tag: "Minimale Vertrauensstufe um ein Tag zu erstellen."
+ max_tags_per_topic: "Maximale Anzahl von Tags, die einem Thema zugeordnet werden können."
+ max_tag_length: "Maximale Anzahl von Zeichen, die in einem Tag verwendet werden können."
+ max_tag_search_results: "Maximale Anzahl von Ergebnissen, die bei der Suche nach Tags angezeigt werden."
+ show_filter_by_tag: "Dropdown-Liste zum Filtern von Theman nach Tag anzeigen."
+ max_tags_in_filter_list: "Maximale Anzahl von Tags in der Dropdown-Liste. Die meist genutzten Tags werden angezeigt."
+ tags_sort_alphabetically: "Anzeige der Tags in alphabetischer Reihenfolge. Standard ist die Sortierung nach Beliebtheit."
+ tag_style: "Visuelle Darstellung der Tag-Schildchen."
+ staff_tags: "Eine Liste von Tags, die nur von Mitarbeitern verwendet werden können"
+ min_trust_level_to_tag_topics: "Minimal benötigte Vertrauensstufe zum Taggen von Themen"
+ suppress_overlapping_tags_in_list: "Verstecke Tags in Listen, wenn diese mit dem Titel überlappen"
+ remove_muted_tags_from_latest: "Zeige Themen mit stummgeschalteten Tags nicht in der Liste der aktuellen Themen an."
errors:
invalid_email: "Ungültige E-Mail-Adresse"
invalid_username: "Es gibt keinen Benutzer mit diesem Benutzernamen."
@@ -2048,3 +2061,9 @@ de:
activemodel:
errors:
<<: *errors
+ tags:
+ staff_tag_disallowed: "Das Tag \"%{tag}\" kann nur von Mitarbeitern hinzugefügt werden."
+ staff_tag_remove_disallowed: "Das Tag \"%{tag}\" kann nur von Mitarbeitern entfernt werden."
+ rss_by_tag: "Themen getaggt mit %{tag}"
+ rss_description:
+ tag: "Getaggte Themen"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 4b19733f5..d656359e3 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -1317,6 +1317,20 @@ en:
default_categories_tracking: "List of categories that are tracked by default."
default_categories_muted: "List of categories that are muted by default."
+ tagging_enabled: "Enable tags on topics?"
+ min_trust_to_create_tag: "The minimum trust level required to create a tag."
+ max_tags_per_topic: "The maximum tags that can be applied to a topic."
+ max_tag_length: "The maximum amount of characters that can be used in a tag."
+ max_tag_search_results: "When searching for tags, the maxium number of results to show."
+ show_filter_by_tag: "Show a dropdown to filter a topic list by tag."
+ max_tags_in_filter_list: "Maximum number of tags to show in the filter dropdown. The most used tags will be shown."
+ tags_sort_alphabetically: "Show tags in alphabetical order. Default is to show in order of popularity."
+ tag_style: "Visual style for tag badges."
+ staff_tags: "A list of tags that can only be applied by staff members"
+ min_trust_level_to_tag_topics: "Minimum trust level required to tag topics"
+ suppress_overlapping_tags_in_list: "Hide tags from list views, if they overlap with title"
+ remove_muted_tags_from_latest: "Don't show topics tagged with muted tags in the latest topic list."
+
errors:
invalid_email: "Invalid email address."
invalid_username: "There's no user with that username."
@@ -3006,3 +3020,10 @@ en:
topic_invite:
user_exists: "Sorry, that user has already been invited. You may only invite a user to a topic once."
+
+ tags:
+ staff_tag_disallowed: "The tag \"%{tag}\" may only be applied by staff."
+ staff_tag_remove_disallowed: "The tag \"%{tag}\" may only be removed by staff."
+ rss_by_tag: "Topics tagged %{tag}"
+ rss_description:
+ tag: "Tagged topics"
diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml
index 9b9d1c42d..49cb33a84 100644
--- a/config/locales/server.es.yml
+++ b/config/locales/server.es.yml
@@ -1110,6 +1110,19 @@ es:
default_categories_watching: "Lista de categorías que están vigiladas por defecto."
default_categories_tracking: "Lista de categorías que están seguidas por defecto"
default_categories_muted: "Lista de categorías que están silenciadas por defecto."
+ tagging_enabled: "¿Permitir a los usuarios etiquetar temas?"
+ min_trust_to_create_tag: "Mínimo nivel de confianza requerido para crear una etiqueta."
+ max_tags_per_topic: "Número máximo de etiquetas que pueden añadirse a un tema."
+ max_tag_length: "Longitud máxima de caracteres que puede tener el nombre de una etiqueta."
+ max_tag_search_results: "Máximo número de resultados a mostrar al buscar etiquetas."
+ show_filter_by_tag: "Mostrar un desplegable para filtrar la lista de temas por etiqueta."
+ max_tags_in_filter_list: "Máximo número de etiquetas a mostrar en el desplegable. Se mostrarán las más usadas."
+ tags_sort_alphabetically: "Mostrar etiquetas en orden alfabético. Por defecto se muestran por popularidad."
+ tag_style: "Estilo visual de los distintivos de etiqueta."
+ staff_tags: "Una lista de etiquetas que sólo podrá ser aplicada por administradores o moderadores"
+ min_trust_level_to_tag_topics: "Mínimo nivel de confianza requerido para etiquetar temas"
+ suppress_overlapping_tags_in_list: "Ocultar etiquetas de la vista de listado si se solapan con el título"
+ remove_muted_tags_from_latest: "No mostrar temas etiquetados con etiquetas silenciadas en la lista de temas recientes."
errors:
invalid_email: "Dirección de correo electrónico inválida. "
invalid_username: "No existe ningún usuario con ese nombre de usuario. "
@@ -2228,3 +2241,9 @@ es:
activemodel:
errors:
<<: *errors
+ tags:
+ staff_tag_disallowed: "La etiqueta \"%{tag}\" sólo puede ser aplicada por los administradores."
+ staff_tag_remove_disallowed: "La etiqueta \"%{tag}\" sólo puede ser eliminada por los administradores."
+ rss_by_tag: "Temas con la etiqueta %{tag}"
+ rss_description:
+ tag: "Temas etiquetados"
diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml
index d367f254f..34a3cfcf4 100644
--- a/config/locales/server.fa_IR.yml
+++ b/config/locales/server.fa_IR.yml
@@ -913,6 +913,10 @@ fa_IR:
emoji_set: "میخواهید ایموجی شما چطور باشد؟"
enforce_square_emoji: "تحمیل نسبت ابعاد مربع به تمام شکلک ها emojis . "
approve_unless_trust_level: "نوشته ها برای کاربران پایین ت از این سطح اعتماد نیاز به تایید دارد. "
+ tagging_enabled: "کاربران اجازه انتخاب برچسب برای موضوعات داشته باشند?"
+ min_trust_to_create_tag: "حداقل سطح اعتماد مورد نیاز برای انتخاب برچسب؟."
+ max_tags_per_topic: "حداکثر تعداد برچسب انتخابی برای موضوع."
+ max_tag_length: "حداقل کراکتر یک نوشته برای برچسب انتخابی."
errors:
invalid_email: "آدرس ایمیل نامعتبر"
invalid_username: "هیچ کاربری با این نام کاربری وجود ندارد."
@@ -1291,3 +1295,6 @@ fa_IR:
activemodel:
errors:
<<: *errors
+ rss_by_tag: "موضوعات برچسب خورد %{tag}"
+ rss_description:
+ tag: "موضوعات برچسب خورد"
diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml
index 77b404e58..9770a1a23 100644
--- a/config/locales/server.fi.yml
+++ b/config/locales/server.fi.yml
@@ -1112,6 +1112,10 @@ fi:
default_categories_watching: "Lista oletuksena tarkkailtavista alueista."
default_categories_tracking: "Lista oletuksena seurattavista alueista."
default_categories_muted: "Lista oletuksena vaimennetuista alueista."
+ tagging_enabled: "Salli käyttäjien tagata viestejä?"
+ min_trust_to_create_tag: "Alin luottamustaso tagin luomiseen."
+ max_tags_per_topic: "Tagien maksimiäärä per aihe."
+ max_tag_length: "Tagien merkkien maksimimäärä."
errors:
invalid_email: "Sähköpostiosoite ei kelpaa."
invalid_username: "Tällä nimellä ei löydy käyttäjää."
@@ -2270,3 +2274,6 @@ fi:
activemodel:
errors:
<<: *errors
+ rss_by_tag: "Aiheet tagattu %{tag}"
+ rss_description:
+ tag: "Tagatut aiheet"
diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml
index 0ed972340..b6900673d 100644
--- a/config/locales/server.fr.yml
+++ b/config/locales/server.fr.yml
@@ -1094,6 +1094,10 @@ fr:
default_categories_watching: "Liste de catégories surveillées par défaut."
default_categories_tracking: "Liste de catégories suivies par défaut."
default_categories_muted: "Liste de catégories silencées par défaut."
+ tagging_enabled: "Autoriser les utilisateurs à mettre des tags sur les sujets ?"
+ min_trust_to_create_tag: "Le niveau de confiance requis pour créer un tag."
+ max_tags_per_topic: "Le nombre maximum de tags qui peuvent être ajouté à un sujet."
+ max_tag_length: "The nombre maximum de caractères qui peuvent être utilisés pour un tag."
errors:
invalid_email: "Adresse de courriel invalide."
invalid_username: "Il n'y a pas d'utilisateur ayant ce pseudo."
@@ -2193,3 +2197,6 @@ fr:
activemodel:
errors:
<<: *errors
+ rss_by_tag: "Sujets portant le tag %{tag}"
+ rss_description:
+ tag: "Sujet tagués"
diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml
index f8786663a..b91f1c7ff 100644
--- a/config/locales/server.pl_PL.yml
+++ b/config/locales/server.pl_PL.yml
@@ -821,6 +821,10 @@ pl_PL:
approve_unless_trust_level: "Posty użytkowników poniżej tego poziomu zaufania muszą być zatwierdzane"
default_categories_watching: "Lista kategorii obserwowanych domyślnie."
default_categories_tracking: "Lista kategorii śledzonych domyślnie."
+ tagging_enabled: "Pozwolić użytkownikom na tagowanie tematów?"
+ min_trust_to_create_tag: "Minimalny poziom zaufania dla tworzenia nowych tagów."
+ max_tags_per_topic: "Maksymalna ilość tagów przypisanych do tematu."
+ max_tag_length: "Maksymalna ilość znaków per tag."
errors:
invalid_email: "Nieprawidłowy adres email."
invalid_username: "Użytkownik o takiej nazwie nie istnieje."
@@ -1216,3 +1220,6 @@ pl_PL:
activemodel:
errors:
<<: *errors
+ rss_by_tag: "Tematy otagowane jako %{tag}"
+ rss_description:
+ tag: "Otagowane tematy"
diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml
index e1f67d2fc..e7882be42 100644
--- a/config/locales/server.pt_BR.yml
+++ b/config/locales/server.pt_BR.yml
@@ -1002,6 +1002,19 @@ pt_BR:
emoji_set: "Como você gostaria do seu emoji?"
enforce_square_emoji: "Forçar proporção quadrangular para todos emojis."
approve_unless_trust_level: "Mensagens para os usuários abaixo deste nível de confiança devem ser aprovados"
+ tagging_enabled: "Permitir que usuários coloquem tags em tópicos?"
+ min_trust_to_create_tag: "O nível de confiança mínimo necessário para criar uma tag."
+ max_tags_per_topic: "O número máximo de tags que podem ser aplicados a um tópico."
+ max_tag_length: "O número máximo de caracteres que pode ser usado em uma tag."
+ max_tag_search_results: "Quando buscando por tags, o número máximo de resultados a exibir."
+ show_filter_by_tag: "Exibir um dropdown para filtrar uma lista de tópicos por uma tag."
+ max_tags_in_filter_list: "Número máximo de tags no filtro do dropdown. As tags mais utilizadas serão exibidas."
+ tags_sort_alphabetically: "Exibir tags em ordem alfabetica. O padrão é exibí-las em ordem de popularidade."
+ tag_style: "Estilo visual para as insígnias de tag."
+ staff_tags: "Uma lista de tags que só podem ser aplicadas por membros da moderação"
+ min_trust_level_to_tag_topics: "Nível de confiança mínimo necessário para aplicar uma tag"
+ suppress_overlapping_tags_in_list: "Esconder tags das visualizações de lista, se elas se sobreporem ao título"
+ remove_muted_tags_from_latest: "Não mostrar tópicos com tags silenciadas na lista de tópicos recentes."
errors:
invalid_email: "Endereço de email inválido"
invalid_username: "Não há nenhum usuário com esse nome de usuário."
@@ -1516,3 +1529,9 @@ pt_BR:
activemodel:
errors:
<<: *errors
+ tags:
+ staff_tag_disallowed: "A tag \"%{tag}\" só pode ser aplicada pela moderação."
+ staff_tag_remove_disallowed: "A tag \"%{tag}\" só pode ser removida pela moderação."
+ rss_by_tag: "Tópicos com a tag %{tag}"
+ rss_description:
+ tag: "Tópicos com tag"
diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml
index 0bf20b989..a31e114a6 100644
--- a/config/locales/server.tr_TR.yml
+++ b/config/locales/server.tr_TR.yml
@@ -984,6 +984,10 @@ tr_TR:
default_categories_watching: "Öntanımlı olarak, izlenen kategorilerin listesi."
default_categories_tracking: "Öntanımlı olarak, takip edilen kategorilerin listesi."
default_categories_muted: "Öntanımlı olarak, sesi kısılan kategorilerin listesi."
+ tagging_enabled: "Kullanıcılar konularına etiket ekleyebilsinler mi?"
+ min_trust_to_create_tag: "Etiket oluşturmak için gereken minumum güven seviyesi."
+ max_tags_per_topic: "Bir konu en fazla kaç adet etiket eklenebilir."
+ max_tag_length: "Bir etiket en fazla kaç karakterde oluşabilir."
errors:
invalid_email: "Geçersiz e-posta adresi."
invalid_username: "Bu kullanıcı adı ile bir kullanıcı bulunmuyor."
@@ -1452,3 +1456,6 @@ tr_TR:
activemodel:
errors:
<<: *errors
+ rss_by_tag: "Konu %{tag} ile etiketlenmiştir."
+ rss_description:
+ tag: "Etiketlenmiş konular"
diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml
index a8b27058e..ec818080b 100644
--- a/config/locales/server.zh_CN.yml
+++ b/config/locales/server.zh_CN.yml
@@ -1079,6 +1079,18 @@ zh_CN:
default_categories_watching: "分类列表默认跟踪。"
default_categories_tracking: "分类列表默认追踪。"
default_categories_muted: "分类列表默认不显示。"
+ tagging_enabled: "允许用户为主题设置标签?"
+ min_trust_to_create_tag: "允许创建标签的最小信任等级。"
+ max_tags_per_topic: "一个主题最多允许有多少个标签。"
+ max_tag_length: "一个标签允许的最大字符数。"
+ max_tag_search_results: "当搜索标签时,显示的最多几个结果。"
+ show_filter_by_tag: "显示一个下拉菜单按照标签过滤主题列表。"
+ max_tags_in_filter_list: "过滤下拉菜单中显示的最大标签数。最常用的标签将优先显示。"
+ tags_sort_alphabetically: "按照字母顺序显示标签。默认显示顺序是流行度。"
+ tag_style: "标签的视觉样式。"
+ staff_tags: "只可由志愿设置的标签列表"
+ min_trust_level_to_tag_topics: "给主题加标签的最小信任等级"
+ suppress_overlapping_tags_in_list: "如果在列表视图中标签覆盖了主题,则隐藏标签"
errors:
invalid_email: "电子邮箱地址无效。"
invalid_username: "没有这个用户名的用户。"
@@ -2452,3 +2464,9 @@ zh_CN:
activemodel:
errors:
<<: *errors
+ tags:
+ staff_tag_disallowed: "标签\"%{tag}\"只可以由职员标记。"
+ staff_tag_remove_disallowed: "标签\"%{tag}\"只可以由职员删除。"
+ rss_by_tag: "%{tag}标签的主题"
+ rss_description:
+ tag: "加标签的主题"
diff --git a/config/routes.rb b/config/routes.rb
index 69a57eff7..b1e72d24a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -606,6 +606,29 @@ Discourse::Application.routes.draw do
get "manifest.json" => "metadata#manifest", as: :manifest
get "opensearch" => "metadata#opensearch", format: :xml
+ scope "/tags" do
+ get '/' => 'tags#index'
+ get '/filter/list' => 'tags#index'
+ get '/filter/search' => 'tags#search'
+ get '/check' => 'tags#check_hashtag'
+ constraints(tag_id: /[^\/]+?/, format: /json|rss/) do
+ get '/:tag_id.rss' => 'tags#tag_feed'
+ get '/:tag_id' => 'tags#show', as: 'list_by_tag'
+ get '/c/:category/:tag_id' => 'tags#show'
+ get '/c/:parent_category/:category/:tag_id' => 'tags#show'
+ get '/:tag_id/notifications' => 'tags#notifications'
+ put '/:tag_id/notifications' => 'tags#update_notifications'
+ put '/:tag_id' => 'tags#update'
+ delete '/:tag_id' => 'tags#destroy'
+
+ Discourse.filters.each do |filter|
+ get "/:tag_id/l/#{filter}" => "tags#show_#{filter}"
+ get "/c/:category/:tag_id/l/#{filter}" => "tags#show_#{filter}"
+ get "/c/:parent_category/:category/:tag_id/l/#{filter}" => "tags#show_#{filter}"
+ end
+ end
+ end
+
Discourse.filters.each do |filter|
root to: "list##{filter}", constraints: HomePageConstraint.new("#{filter}"), :as => "list_#{filter}"
end
diff --git a/config/site_settings.yml b/config/site_settings.yml
index ea6fdf532..3a593ce3e 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -1157,3 +1157,57 @@ user_preferences:
default_categories_muted:
type: category_list
default: ''
+
+tags:
+ tagging_enabled:
+ client: true
+ default: false
+ refresh: true
+ tag_style:
+ client: true
+ type: enum
+ default: 'simple'
+ choices:
+ - simple
+ - bullet
+ - box
+ preview: '
tag1tag2
'
+ max_tags_per_topic:
+ default: 5
+ client: true
+ max_tag_length:
+ default: 20
+ client: true
+ min_trust_to_create_tag:
+ default: 3
+ enum: 'TrustLevelSetting'
+ min_trust_level_to_tag_topics:
+ default: 0
+ enum: 'TrustLevelSetting'
+ client: true
+ max_tag_search_results:
+ client: true
+ default: 5
+ min: 1
+ show_filter_by_tag:
+ client: true
+ default: false
+ refresh: true
+ max_tags_in_filter_list:
+ default: 30
+ min: 1
+ refresh: true
+ tags_sort_alphabetically:
+ client: true
+ default: false
+ refresh: true
+ staff_tags:
+ type: list
+ client: true
+ default: ''
+ suppress_overlapping_tags_in_list:
+ default: false
+ client: true
+ remove_muted_tags_from_latest:
+ default: false
+
diff --git a/lib/discourse_tagging.rb b/lib/discourse_tagging.rb
new file mode 100644
index 000000000..944f8bfeb
--- /dev/null
+++ b/lib/discourse_tagging.rb
@@ -0,0 +1,116 @@
+module DiscourseTagging
+
+ TAGS_FIELD_NAME = "tags"
+ TAGS_FILTER_REGEXP = /[<\\\/\>\#\?\&\s]/
+
+ # class Engine < ::Rails::Engine
+ # engine_name "discourse_tagging"
+ # isolate_namespace DiscourseTagging
+ # end
+
+ def self.clean_tag(tag)
+ tag.downcase.strip[0...SiteSetting.max_tag_length].gsub(TAGS_FILTER_REGEXP, '')
+ end
+
+ def self.staff_only_tags(tags)
+ return nil if tags.nil?
+
+ staff_tags = SiteSetting.staff_tags.split("|")
+
+ tag_diff = tags - staff_tags
+ tag_diff = tags - tag_diff
+
+ tag_diff.present? ? tag_diff : nil
+ end
+
+ def self.tags_for_saving(tags, guardian)
+
+ return [] unless guardian.can_tag_topics?
+
+ return unless tags
+
+ tags.map! {|t| clean_tag(t) }
+ tags.delete_if {|t| t.blank? }
+ tags.uniq!
+
+ # If the user can't create tags, remove any tags that don't already exist
+ # TODO: this is doing a full count, it should just check first or use a cache
+ unless guardian.can_create_tag?
+ tag_count = TopicCustomField.where(name: TAGS_FIELD_NAME, value: tags).group(:value).count
+ tags.delete_if {|t| !tag_count.has_key?(t) }
+ end
+
+ return tags[0...SiteSetting.max_tags_per_topic]
+ end
+
+ def self.notification_key(tag_id)
+ "tags_notification:#{tag_id}"
+ end
+
+ def self.auto_notify_for(tags, topic)
+ # This insert will run up to SiteSetting.max_tags_per_topic times
+ tags.each do |tag|
+ key_name_sql = ActiveRecord::Base.sql_fragment("('#{notification_key(tag)}')", tag)
+
+ sql = <<-SQL
+ INSERT INTO topic_users(user_id, topic_id, notification_level, notifications_reason_id)
+ SELECT ucf.user_id,
+ #{topic.id.to_i},
+ CAST(ucf.value AS INTEGER),
+ #{TopicUser.notification_reasons[:plugin_changed]}
+ FROM user_custom_fields AS ucf
+ WHERE ucf.name IN #{key_name_sql}
+ AND NOT EXISTS(SELECT 1 FROM topic_users WHERE topic_id = #{topic.id.to_i} AND user_id = ucf.user_id)
+ AND CAST(ucf.value AS INTEGER) <> #{TopicUser.notification_levels[:regular]}
+ SQL
+
+ ActiveRecord::Base.exec_sql(sql)
+ end
+ end
+
+ def self.rename_tag(current_user, old_id, new_id)
+ sql = <<-SQL
+ UPDATE topic_custom_fields AS tcf
+ SET value = :new_id
+ WHERE value = :old_id
+ AND name = :tags_field_name
+ AND NOT EXISTS(SELECT 1
+ FROM topic_custom_fields
+ WHERE value = :new_id AND name = :tags_field_name AND topic_id = tcf.topic_id)
+ SQL
+
+ user_sql = <<-SQL
+ UPDATE user_custom_fields
+ SET name = :new_user_tag_id
+ WHERE name = :old_user_tag_id
+ AND NOT EXISTS(SELECT 1
+ FROM user_custom_fields
+ WHERE name = :new_user_tag_id)
+ SQL
+
+ ActiveRecord::Base.transaction do
+ ActiveRecord::Base.exec_sql(sql, new_id: new_id, old_id: old_id, tags_field_name: TAGS_FIELD_NAME)
+ TopicCustomField.delete_all(name: TAGS_FIELD_NAME, value: old_id)
+ ActiveRecord::Base.exec_sql(user_sql, new_user_tag_id: notification_key(new_id),
+ old_user_tag_id: notification_key(old_id))
+ UserCustomField.delete_all(name: notification_key(old_id))
+ StaffActionLogger.new(current_user).log_custom('renamed_tag', previous_value: old_id, new_value: new_id)
+ end
+ end
+
+ def self.top_tags(limit_arg=nil)
+ # TODO: cache
+ # TODO: need an index for this (name,value)
+ TopicCustomField.where(name: TAGS_FIELD_NAME)
+ .group(:value)
+ .limit(limit_arg || SiteSetting.max_tags_in_filter_list)
+ .order('COUNT(value) DESC')
+ .count
+ .map {|name, count| name}
+ end
+
+ def self.muted_tags(user)
+ return [] unless user
+ UserCustomField.where(user_id: user.id, value: TopicUser.notification_levels[:muted]).pluck(:name).map { |x| x[0,17] == "tags_notification" ? x[18..-1] : nil}.compact
+ end
+end
diff --git a/lib/guardian.rb b/lib/guardian.rb
index 5821e6c03..1a6c9d137 100644
--- a/lib/guardian.rb
+++ b/lib/guardian.rb
@@ -276,6 +276,18 @@ class Guardian
UserExport.where(user_id: @user.id, created_at: (Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)).count == 0
end
+ def can_create_tag?
+ user && user.has_trust_level?(SiteSetting.min_trust_to_create_tag.to_i)
+ end
+
+ def can_tag_topics?
+ user && user.has_trust_level?(SiteSetting.min_trust_level_to_tag_topics.to_i)
+ end
+
+ def can_admin_tags?
+ is_staff?
+ end
+
private
def is_my_own?(obj)
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index 7fb3735de..cccc8aa67 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -30,6 +30,10 @@ class Plugin::Instance
[].tap { |plugins|
# also follows symlinks - http://stackoverflow.com/q/357754
Dir["#{parent_path}/**/*/**/plugin.rb"].sort.each do |path|
+
+ # tagging is included in core, so don't load it
+ next if path =~ /discourse-tagging/
+
source = File.read(path)
metadata = Plugin::Metadata.parse(source)
plugins << self.new(metadata, path)
diff --git a/lib/post_creator.rb b/lib/post_creator.rb
index 9f81977ec..bd0d67295 100644
--- a/lib/post_creator.rb
+++ b/lib/post_creator.rb
@@ -147,6 +147,7 @@ class PostCreator
track_latest_on_category
enqueue_jobs
BadgeGranter.queue_badge_grant(Badge::Trigger::PostRevision, post: @post)
+ auto_notify_for_tags
trigger_after_events(@post)
@@ -437,6 +438,15 @@ class PostCreator
PostJobsEnqueuer.new(@post, @topic, new_topic?, {import_mode: @opts[:import_mode]}).enqueue_jobs
end
+ def auto_notify_for_tags
+ tags = DiscourseTagging.tags_for_saving(@opts[:tags], @guardian)
+ if tags.present?
+ @topic.custom_fields.update(DiscourseTagging::TAGS_FIELD_NAME => tags)
+ @topic.save
+ DiscourseTagging.auto_notify_for(tags, @topic)
+ end
+ end
+
def new_topic?
@opts[:topic_id].blank?
end
diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb
index 093b55c92..d1fb4bcea 100644
--- a/lib/post_revisor.rb
+++ b/lib/post_revisor.rb
@@ -72,6 +72,54 @@ class PostRevisor
tc.check_result(tc.topic.change_category_to_id(category_id))
end
+ track_topic_field(:tags_empty_array) do |tc, val|
+ if val.present?
+ unless tc.guardian.is_staff?
+ old_tags = tc.topic.tags || []
+ staff_tags = DiscourseTagging.staff_only_tags(old_tags)
+ if staff_tags.present?
+ tc.topic.errors[:base] << I18n.t("tags.staff_tag_remove_disallowed", tag: staff_tags.join(" "))
+ tc.check_result(false)
+ next
+ end
+ end
+
+ tc.record_change(DiscourseTagging::TAGS_FIELD_NAME, tc.topic.custom_fields[DiscourseTagging::TAGS_FIELD_NAME], nil)
+ tc.topic.custom_fields.delete(DiscourseTagging::TAGS_FIELD_NAME)
+ end
+ end
+
+ track_topic_field(:tags) do |tc, tags|
+ if tags.present? && tc.guardian.can_tag_topics?
+ tags = DiscourseTagging.tags_for_saving(tags, tc.guardian)
+ old_tags = tc.topic.tags || []
+
+ new_tags = tags - old_tags
+ removed_tags = old_tags - tags
+
+ unless tc.guardian.is_staff?
+ staff_tags = DiscourseTagging.staff_only_tags(new_tags)
+ if staff_tags.present?
+ tc.topic.errors[:base] << I18n.t("tags.staff_tag_disallowed", tag: staff_tags.join(" "))
+ tc.check_result(false)
+ next
+ end
+
+ staff_tags = DiscourseTagging.staff_only_tags(removed_tags)
+ if staff_tags.present?
+ tc.topic.errors[:base] << I18n.t("tags.staff_tag_remove_disallowed", tag: staff_tags.join(" "))
+ tc.check_result(false)
+ next
+ end
+ end
+
+ tc.record_change(DiscourseTagging::TAGS_FIELD_NAME, tc.topic.custom_fields[DiscourseTagging::TAGS_FIELD_NAME], tags)
+ tc.topic.custom_fields.update(DiscourseTagging::TAGS_FIELD_NAME => tags)
+
+ DiscourseTagging.auto_notify_for(new_tags, tc.topic) if new_tags.present?
+ end
+ end
+
# AVAILABLE OPTIONS:
# - revised_at: changes the date of the revision
# - force_new_version: bypass ninja-edit window
diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb
index bc804a161..0c35f70b0 100644
--- a/lib/pretty_text.rb
+++ b/lib/pretty_text.rb
@@ -67,6 +67,23 @@ module PrettyText
}
end
end
+
+ def category_tag_hashtag_lookup(text)
+ tag_postfix = '::tag'
+ is_tag = text =~ /#{tag_postfix}$/
+
+ if !is_tag && category = Category.query_from_hashtag_slug(text)
+ [category.url_with_id, text]
+ elsif is_tag && tag = TopicCustomField.find_by(name: TAGS_FIELD_NAME, value: text.gsub!("#{tag_postfix}", ''))
+ ["#{Discourse.base_url}/tags/#{tag.value}", text]
+ else
+ nil
+ end
+ end
+
+ DiscourseEvent.on(:markdown_context) do |context|
+ context.eval('opts["categoryHashtagLookup"] = function(c){return helpers.category_tag_hashtag_lookup(c);}')
+ end
end
@mutex = Mutex.new
diff --git a/lib/search.rb b/lib/search.rb
index 5bfd9d4e2..224c14c35 100644
--- a/lib/search.rb
+++ b/lib/search.rb
@@ -313,6 +313,17 @@ class Search
end
end
+ advanced_filter(/tags?:([a-zA-Z0-9,\-_]+)/) do |posts, match|
+ tags = match.split(",")
+
+ posts.where("topics.id IN (
+ SELECT tc.topic_id
+ FROM topic_custom_fields tc
+ WHERE tc.name = '#{DiscourseTagging::TAGS_FIELD_NAME}' AND
+ tc.value in (?)
+ )", tags)
+ end
+
private
diff --git a/lib/topic_creator.rb b/lib/topic_creator.rb
index d0548885d..53409a183 100644
--- a/lib/topic_creator.rb
+++ b/lib/topic_creator.rb
@@ -23,6 +23,12 @@ class TopicCreator
# so we fire the validation event after
# this allows us to add errors
valid = topic.valid?
+
+ # not sure where this should go
+ if !@guardian.is_staff? && staff_only = DiscourseTagging.staff_only_tags(@opts[:tags])
+ topic.errors[:base] << I18n.t("tags.staff_tag_disallowed", tag: staff_only.join(" "))
+ end
+
DiscourseEvent.trigger(:after_validate_topic, topic, self)
valid &&= topic.errors.empty?
diff --git a/lib/topic_query.rb b/lib/topic_query.rb
index 1c061107c..f14c3dca4 100644
--- a/lib/topic_query.rb
+++ b/lib/topic_query.rb
@@ -308,6 +308,7 @@ class TopicQuery
result = default_results(options)
result = remove_muted_topics(result, @user) unless options && options[:state] == "muted".freeze
result = remove_muted_categories(result, @user, exclude: options[:category])
+ result = remove_muted_tags(result, @user, options)
# plugins can remove topics here:
self.class.results_filter_callbacks.each do |filter_callback|
@@ -334,6 +335,7 @@ class TopicQuery
result = TopicQuery.new_filter(default_results(options.reverse_merge(:unordered => true)), @user.user_option.treat_as_new_topic_start_date)
result = remove_muted_topics(result, @user)
result = remove_muted_categories(result, @user, exclude: options[:category])
+ result = remove_muted_tags(result, @user, options)
self.class.results_filter_callbacks.each do |filter_callback|
result = filter_callback.call(:new, result, @user, options)
@@ -562,6 +564,36 @@ class TopicQuery
list
end
+ def remove_muted_tags(list, user, opts=nil)
+ if user.nil? || !SiteSetting.tagging_enabled || !SiteSetting.remove_muted_tags_from_latest
+ list
+ else
+ muted_tags = DiscourseTagging.muted_tags(user)
+ if muted_tags.empty?
+ list
+ else
+ showing_tag = if opts[:filter]
+ f = opts[:filter].split('/')
+ f[0] == 'tags' ? f[1] : nil
+ else
+ nil
+ end
+
+ if muted_tags.include?(showing_tag)
+ list # if viewing the topic list for a muted tag, show all the topics
+ else
+ arr = muted_tags.map{ |z| "'#{z}'" }.join(',')
+ list.where("EXISTS (
+ SELECT 1
+ FROM topic_custom_fields tcf
+ WHERE tcf.name = 'tags'
+ AND tcf.value NOT IN (#{arr})
+ AND tcf.topic_id = topics.id
+ ) OR NOT EXISTS (select 1 from topic_custom_fields tcf where tcf.name = 'tags' and tcf.topic_id = topics.id)")
+ end
+ end
+ end
+ end
def new_messages(params)
diff --git a/lib/topics_bulk_action.rb b/lib/topics_bulk_action.rb
index 541d283a1..36c17f228 100644
--- a/lib/topics_bulk_action.rb
+++ b/lib/topics_bulk_action.rb
@@ -11,7 +11,7 @@ class TopicsBulkAction
def self.operations
@operations ||= %w(change_category close archive change_notification_level
reset_read dismiss_posts delete unlist archive_messages
- move_messages_to_inbox)
+ move_messages_to_inbox change_tags)
end
def self.register_operation(name, &block)
@@ -130,6 +130,23 @@ class TopicsBulkAction
end
end
+ def change_tags
+ tags = @operation[:tags]
+ tags = DiscourseTagging.tags_for_saving(tags, guardian) if tags.present?
+
+ topics.each do |t|
+ if guardian.can_edit?(t)
+ if tags.present?
+ t.custom_fields.update(DiscourseTagging::TAGS_FIELD_NAME => tags)
+ t.save
+ DiscourseTagging.auto_notify_for(tags, t)
+ else
+ t.custom_fields.delete(DiscourseTagging::TAGS_FIELD_NAME)
+ end
+ end
+ end
+ end
+
def guardian
@guardian ||= Guardian.new(@user)
end