aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Wallabag/CoreBundle/Controller/ExportController.php12
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php2
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php29
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.zh.yml657
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/validators.zh.yml7
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig19
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig21
-rw-r--r--src/Wallabag/UserBundle/Resources/translations/wallabag_user.zh.yml11
8 files changed, 727 insertions, 31 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/ExportController.php b/src/Wallabag/CoreBundle/Controller/ExportController.php
index 282fd733..cec8d499 100644
--- a/src/Wallabag/CoreBundle/Controller/ExportController.php
+++ b/src/Wallabag/CoreBundle/Controller/ExportController.php
@@ -68,6 +68,18 @@ class ExportController extends Controller
68 ); 68 );
69 69
70 $title = 'Tag ' . $tag->getLabel(); 70 $title = 'Tag ' . $tag->getLabel();
71 } elseif ('search' === $category) {
72 $searchTerm = (isset($request->get('search_entry')['term']) ? $request->get('search_entry')['term'] : '');
73 $currentRoute = (null !== $request->query->get('currentRoute') ? $request->query->get('currentRoute') : '');
74
75 $entries = $repository->getBuilderForSearchByUser(
76 $this->getUser()->getId(),
77 $searchTerm,
78 $currentRoute
79 )->getQuery()
80 ->getResult();
81
82 $title = 'Search ' . $searchTerm;
71 } else { 83 } else {
72 $entries = $repository 84 $entries = $repository
73 ->$methodBuilder($this->getUser()->getId()) 85 ->$methodBuilder($this->getUser()->getId())
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index 19045798..0e19a0c2 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -552,7 +552,7 @@ class Entry
552 * 552 *
553 * @return Entry 553 * @return Entry
554 */ 554 */
555 public function setCreatedAt(\DateTime $createdAt) 555 public function setCreatedAt(\DateTimeInterface $createdAt)
556 { 556 {
557 $this->createdAt = $createdAt; 557 $this->createdAt = $createdAt;
558 558
diff --git a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
index 17070c59..61ad99a8 100644
--- a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
@@ -73,23 +73,22 @@ class EntryFilterType extends AbstractType
73 'label' => 'entry.filters.reading_time.label', 73 'label' => 'entry.filters.reading_time.label',
74 ]) 74 ])
75 ->add('createdAt', DateRangeFilterType::class, [ 75 ->add('createdAt', DateRangeFilterType::class, [
76 'left_date_options' => [ 76 'left_date_options' => [
77 'attr' => [ 77 'attr' => [
78 'placeholder' => 'dd/mm/yyyy', 78 'placeholder' => 'yyyy-mm-dd',
79 ],
80 'format' => 'dd/MM/yyyy',
81 'widget' => 'single_text',
82 ], 79 ],
83 'right_date_options' => [ 80 'format' => 'yyyy-MM-dd',
84 'attr' => [ 81 'widget' => 'single_text',
85 'placeholder' => 'dd/mm/yyyy', 82 ],
86 ], 83 'right_date_options' => [
87 'format' => 'dd/MM/yyyy', 84 'attr' => [
88 'widget' => 'single_text', 85 'placeholder' => 'yyyy-mm-dd',
89 ], 86 ],
90 'label' => 'entry.filters.created_at.label', 87 'format' => 'yyyy-MM-dd',
91 ] 88 'widget' => 'single_text',
92 ) 89 ],
90 'label' => 'entry.filters.created_at.label',
91 ])
93 ->add('domainName', TextFilterType::class, [ 92 ->add('domainName', TextFilterType::class, [
94 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { 93 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
95 $value = $values['value']; 94 $value = $values['value'];
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.zh.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.zh.yml
new file mode 100644
index 00000000..21f2f9a7
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.zh.yml
@@ -0,0 +1,657 @@
1security:
2 login:
3 page_title: '欢迎来到 wallabag!'
4 keep_logged_in: '保持登入状态'
5 forgot_password: '不记得密码?'
6 submit: '登录'
7 register: '注册'
8 username: '用户名'
9 password: '密码'
10 cancel: '取消'
11 resetting:
12 description: "请在下方输入你的邮箱地址,我们会向你发送关于重设密码的指示。"
13 register:
14 page_title: '创建一个新账户'
15 go_to_account: '前往你的账户'
16
17menu:
18 left:
19 unread: '未读'
20 starred: '星标'
21 archive: '存档'
22 all_articles: '所有项目'
23 config: '配置'
24 tags: '标签'
25 internal_settings: '内部设置'
26 import: '导入'
27 howto: '教程'
28 developer: 'API 客户端管理'
29 logout: '登出'
30 about: '关于'
31 search: '搜索'
32 save_link: '保存链接'
33 back_to_unread: '回到未读项目'
34 users_management: '用户管理'
35 site_credentials: '网站凭证'
36 quickstart: "快速开始"
37 top:
38 add_new_entry: '添加新项目'
39 search: '搜索'
40 filter_entries: '筛选项目'
41 random_entry: '随机跳到该列表中的一个项目'
42 export: '导出'
43 search_form:
44 input_label: '输入搜索关键词'
45
46footer:
47 wallabag:
48 elsewhere: '将 wallabag 随身携带'
49 social: '社交'
50 powered_by: '运行'
51 about: '关于'
52 stats: '自从 %user_creation% 以来你已经读了 %nb_archives% 篇文章。 这相当于每天 %per_day% 篇!'
53
54config:
55 page_title: '配置'
56 tab_menu:
57 settings: '设置'
58 feed: '订阅源'
59 user_info: '用户信息'
60 password: '密码'
61 rules: '标签规则'
62 new_user: '添加用户'
63 reset: '重置区域'
64 form:
65 save: '保存'
66 form_settings:
67 theme_label: '主题'
68 items_per_page_label: '每页项目数'
69 language_label: '语言'
70 reading_speed:
71 label: '阅读速度(词 / 每分钟)'
72 help_message: '你可以使用在线工具来估计自己的阅读速度:'
73 action_mark_as_read:
74 label: '将一个项目删除、加星标或是标记为已读后该做什么?'
75 redirect_homepage: '返回主页'
76 redirect_current_page: '停留在当前页面'
77 pocket_consumer_key_label: '用于从 Pocket 导入内容的 consumer key'
78 android_configuration: '配置你的安卓应用程序'
79 android_instruction: "点按此处以预先填充您的 Android 应用"
80 help_theme: "wallabag 是可定制的,你可以在这里选择你喜欢的主题。"
81 help_items_per_page: "你可以选择每页显示的文章数目。"
82 help_reading_speed: "wallabag 会为每篇文章计算阅读时间,你可以通过这个列表选择自己是个速读者或是慢读者。wallabag 会根据你的选择重新计算每篇文章的阅读时间。"
83 help_language: "你可以在此处更改 wallabag 的界面语言。"
84 help_pocket_consumer_key: "导入 Pocket 项目时需要用到。你可以在自己的 Pocket 账户中创建。"
85 form_feed:
86 description: 'wallabag 提供的 Atom 订阅源能方便你在最喜欢的 RSS 阅读器上阅读自己保存的文章,为此你需要先生成一个令牌。'
87 token_label: '订阅源令牌'
88 no_token: '不需要令牌'
89 token_create: '创建令牌'
90 token_reset: '重新生成令牌'
91 token_revoke: '作废令牌'
92 feed_links: '订阅源链接'
93 feed_link:
94 unread: '未读'
95 starred: '星标'
96 archive: '存档'
97 all: '所有'
98 feed_limit: '订阅源包含的最大项目数'
99 form_user:
100 two_factor_description: "开启两步验证后,在每次进行新的未信任登录时,你都需要通过邮件或者 OTP(动态密码)应用(比如 Google Authenticator,Authy 或者 FreeOTP)来获取一次性登陆码。你不能同时选择两项。"
101 login_label: 'Login(无法更改)'
102 name_label: 'Name'
103 email_label: '邮箱'
104 two_factor:
105 emailTwoFactor_label: '使用邮箱(通过邮箱收取登录代码)'
106 googleTwoFactor_label: '使用 OTP(动态密码)应用(通过打开像 Google Authenticator,Authy 或者 FreeOTP 等应用,来获取一次性动态密码)'
107 table_method: '方式'
108 table_state: '状态'
109 table_action: '操作'
110 state_enabled: '启用'
111 state_disabled: '停用'
112 action_email: '使用邮件'
113 action_app: '使用 OTP 应用'
114 delete:
115 title: '删除我的账号(危险区域)'
116 description: '如果你删除你的账号,你的所有文章、标签以及账号本身都会被永久删除(且无法撤销),然后你将会被登出。'
117 confirm: '你真的确定的吗?(这不能被撤销)'
118 button: '删除我的账号'
119 reset:
120 title: '重置区(危险区域)'
121 description: '一旦你点击这个按钮,你就可以移除你账号中的某些信息。请注意这些操作是不可撤销的。'
122 annotations: "删除所有标注"
123 tags: "删除所有标签"
124 entries: "删除所有项目"
125 archived: "删除所有已存档项目"
126 confirm: '你真的确定的吗?(这不能被撤销)'
127 form_password:
128 description: "你可以在此更改你的密码,你的新密码至少应包含 8 个字符"
129 old_password_label: '现有密码'
130 new_password_label: '新密码'
131 repeat_new_password_label: '重新输入新密码'
132 form_rules:
133 if_label: '如果'
134 then_tag_as_label: '那么打上标签'
135 delete_rule_label: '删除'
136 edit_rule_label: '编辑'
137 rule_label: '规则'
138 tags_label: '标签'
139 card:
140 new_tagging_rule: "创建新的标签规则"
141 import_tagging_rules: "导入标签规则"
142 import_tagging_rules_detail: "你需要选择你之前导出得到的 JSON 文件"
143 export_tagging_rules: "导出标签规则"
144 export_tagging_rules_detail: "提供一个 JSON 文件供你下载,可以在别处导入或是用做备份。"
145 file_label: "JSON 文件"
146 import_submit: "导入"
147 export: "导出"
148 faq:
149 title: '常见问题'
150 tagging_rules_definition_title: '« 标签规则 » 是什么意思?'
151 tagging_rules_definition_description: '它们是 wallabag 用来给新项目自动打上标签的规则。<br />每次一个新项目被添加进来时,所有的标签规则都会作用于这个项目,为它打上你配置好的标签,免去你手动分类项目的麻烦。'
152 how_to_use_them_title: '我该怎么使用它们?'
153 how_to_use_them_description: '假设你想要在一个新项目的阅读时间短于 3 分钟时,将其标记为 « <i>短阅读</i> »。<br /> 这样的话,你应该在 <i>规则</i> 区域输入 « readingTime &lt;= 3 »,并在 <i>标签</i> 区域输入 « <i>短阅读</i> »。<br /> 可以同时添加数个标签,只需要用半角逗号来隔开它们: « <i>短阅读, 必读</i> »<br /> 可以使用预定义的操作符来编写复杂的规则:if « <i>readingTime &gt;= 5 AND domainName ="github.com"</i> » then tag as « <i>长阅读, github</i> »'
154 variables_available_title: '我可以使用哪些变量和操作符来编写规则?'
155 variables_available_description: '可以使用以下变量和操作符来编写标签规则:'
156 meaning: '含义'
157 variable_description:
158 label: '变量'
159 title: '项目的标题'
160 url: '项目的链接'
161 isArchived: '项目是否已存档'
162 isStarred: '项目是否带有星标'
163 content: "项目的内容"
164 language: "项目所用语言"
165 mimetype: "项目的互联网媒体类型(mime-type)"
166 readingTime: "项目的预计阅读时间,以分钟为单位"
167 domainName: '项目链接的域名'
168 operator_description:
169 label: '操作符'
170 less_than: '小于等于…'
171 strictly_less_than: '小于…'
172 greater_than: '大于等于…'
173 strictly_greater_than: '大于…'
174 equal_to: '等于…'
175 not_equal_to: '不等于…'
176 or: '“或”操作符'
177 and: '“与”操作符'
178 matches: '当一个<i>域</i>匹配一个<i>搜索模式</i>时为真(不区分大小写)。<br />举例:<code>title matches"football"</code>'
179 notmatches: '当一个<i> 域</i>不匹配一个<i>搜索模式</i>时为真(不区分大小写)。<br />举例: <code>title notmatches"football"</code>'
180 otp:
181 page_title: "两步验证"
182 app:
183 two_factor_code_description_1: '你刚刚启用了基于 OTP(动态密码)的两步验证,打开你的 OTP 应用,使用该代码来得到一次性密码,页面刷新后该代码便会消失'
184 two_factor_code_description_2: '你可以用你的 OTP 应用来扫描这个二维码:'
185 two_factor_code_description_3: '另外,将这些备用码保存在一个安全的地方,以防万一你需要用它们来恢复对 OTP 应用的访问权'
186 two_factor_code_description_4: '从你配置好的应用中测试 OTP 码'
187 cancel: "取消"
188 enable: "启用"
189
190entry:
191 default_title: '项目标题'
192 page_titles:
193 unread: '未读项目'
194 starred: '星标项目'
195 archived: '存档项目'
196 filtered: '筛选后项目'
197 filtered_tags: '根据标签筛选:'
198 filtered_search: '根据搜索筛选:'
199 untagged: '无标签项目'
200 all: '所有项目'
201 list:
202 number_on_the_page: '{0} 没有对应项目。|{1} 有 1 个项目。|]1,Inf[ 有 %count% 个项目。'
203 reading_time: '预计阅读时间'
204 reading_time_minutes: '预计阅读时间:%readingTime% 分钟'
205 reading_time_less_one_minute: '预计阅读时间:&lt; 1 分钟'
206 number_of_tags: '{1}以及 1 个其它标签 |]1,Inf[以及 %count% 个其它标签'
207 reading_time_minutes_short: '%readingTime% 分钟'
208 reading_time_less_one_minute_short: '&lt; 1 分钟'
209 original_article: '原始文章'
210 toogle_as_read: '标记为已读'
211 toogle_as_star: '标星'
212 delete: '删除'
213 export_title: '导出'
214 filters:
215 title: '筛选器'
216 status_label: '状态'
217 archived_label: '已存档'
218 starred_label: '带有星标'
219 unread_label: '未读'
220 preview_picture_label: '有预览图片'
221 preview_picture_help: '预览图片'
222 is_public_label: '有公开链接'
223 is_public_help: '公开链接'
224 language_label: '语言'
225 http_status_label: 'HTTP 状态'
226 reading_time:
227 label: '阅读时间(按分钟计)'
228 from: '从'
229 to: '到'
230 domain_label: '域名'
231 created_at:
232 label: '创建日期'
233 from: '从'
234 to: '到'
235 action:
236 clear: '清除'
237 filter: '筛选'
238 view:
239 left_menu:
240 back_to_top: '返回顶部'
241 back_to_homepage: '返回主页'
242 set_as_read: '标为已读'
243 set_as_unread: '标为未读'
244 set_as_starred: '标星'
245 view_original_article: '原始文章'
246 re_fetch_content: '重新抓取'
247 delete: '删除'
248 add_a_tag: '添加标签'
249 share_content: '分享'
250 share_email_label: '邮件分享'
251 public_link: '公开链接'
252 delete_public_link: '删除公开链接'
253 export: '导出'
254 print: '打印'
255 problem:
256 label: '遇到问题?'
257 description: '这篇文章显示不正常?'
258 edit_title: '编辑标题'
259 original_article: '原始文章'
260 annotations_on_the_entry: '{0} 没有标注|{1} 1 个标注 |]1,Inf[ %count% 个标注'
261 created_at: '创建日期'
262 published_at: '发布日期'
263 published_by: '作者'
264 provided_by: '提供于'
265 new:
266 page_title: '添加新项目'
267 placeholder: 'https://website.com'
268 form_new:
269 url_label: URL
270 search:
271 placeholder: '你要找什么?'
272 edit:
273 page_title: '编辑项目'
274 title_label: '标题'
275 url_label: '链接'
276 origin_url_label: '原始链接(你发现这篇文章的地方)'
277 save_label: '保存'
278 public:
279 shared_by_wallabag: "这篇文章由 %username% 于 <a href='%wallabag_instance%'>wallabag</a> 分享"
280 confirm:
281 delete: "你确定要删除这篇文章吗?"
282 delete_tag: "你确定要从这篇文章删除该标签吗?"
283 metadata:
284 reading_time: "预计阅读时间"
285 reading_time_minutes_short: "%readingTime% 分钟"
286 address: "地址"
287 added_on: "添加于"
288
289about:
290 page_title: '关于'
291 top_menu:
292 who_behind_wallabag: 'wallabag 背后有哪些人'
293 getting_help: '获取帮助'
294 helping: '助力 wallabag 的发展'
295 contributors: '贡献者'
296 third_party: '第三方库'
297 who_behind_wallabag:
298 developped_by: '开发者:'
299 website: '网站'
300 many_contributors: '以及 <a href="https://github.com/wallabag/wallabag/graphs/contributors">GitHub 上</a> 的许多其它贡献者 ♥'
301 project_website: '项目官网'
302 license: '许可证'
303 version: '版本'
304 getting_help:
305 documentation: '文档'
306 bug_reports: 'Bug 报告'
307 support: '<a href="https://github.com/wallabag/wallabag/issues">前往 GitHub</a>'
308 helping:
309 description: 'wallabag 是自由且开源的,你可以帮助我们:'
310 by_contributing: '为项目做出贡献:'
311 by_contributing_2: '这里列出了我们的需求'
312 by_paypal: '通过 Paypal'
313 contributors:
314 description: '感谢为 wallabag 网页程序做出贡献的人们!'
315 third_party:
316 description: '这里是 wallabag 使用的第三方库列表(以及它们的许可证):'
317 package: '包'
318 license: '许可证'
319
320howto:
321 page_title: '教程'
322 tab_menu:
323 add_link: "保存一个链接"
324 shortcuts: "使用快捷键"
325 page_description: '有多种方法可以保存一篇文章:'
326 top_menu:
327 browser_addons: '浏览器扩展'
328 mobile_apps: '移动应用程序'
329 bookmarklet: '浏览器小书签'
330 form:
331 description: '多亏了这个表单'
332 browser_addons:
333 firefox: '火狐浏览器'
334 chrome: 'Chrome 浏览器'
335 opera: 'Opera 浏览器'
336 mobile_apps:
337 android:
338 via_f_droid: '通过 F-Droid'
339 via_google_play: '通过 Google Play'
340 ios: '位于 App Store'
341 windows: '位于 Microsoft Store'
342 bookmarklet:
343 description: '点按并拖动这个链接到你的书签栏上:'
344 shortcuts:
345 page_description: 以下是 wallabag 中可用的快捷键
346 shortcut: 快捷键
347 action: 操作
348 all_pages_title: 所有页面中均可用的快捷键
349 go_unread: 前往未读项目
350 go_starred: 前往星标项目
351 go_archive: 前往存档项目
352 go_all: 前往所有项目
353 go_tags: 前往标签页面
354 go_config: 前往配置页面
355 go_import: 前往导入页面
356 go_developers: 前往开发者页面
357 go_howto: 前往教程(就是这!)
358 go_logout: 登出
359 list_title: 在文章列表页面可用的快捷键
360 search: 显示搜索表单
361 article_title: 在文章页面可用的快捷键
362 open_original: 打开项目的原始链接
363 toggle_favorite: 改变项目的星标状态
364 toggle_archive: 改变项目的已读状态
365 delete: 删除项目
366 material_title: 仅可用于 Material 主题的快捷键
367 add_link: 保存新链接
368 hide_form: 隐藏当前表单(搜索或添加新链接时)
369 arrows_navigation: 在项目间导航
370 open_article: 打开选中项目
371
372quickstart:
373 page_title: '快速开始'
374 more: '更多…'
375 intro:
376 title: '欢迎来到 wallabag!'
377 paragraph_1: "我们会在你访问 wallabag 的旅途中陪伴你,同时向你展示一些可能会让你感兴趣的功能。"
378 paragraph_2: '跟我们来!'
379 configure:
380 title: '配置应用程序'
381 description: '为了得到一个适合你的应用程序,请看一眼 wallabag 的配置页面。'
382 language: '变更语言和设计'
383 feed: '启用订阅源'
384 tagging_rules: '编写规则来给你的文章自动加上标签'
385 admin:
386 title: '管理员'
387 description: '作为一名管理员,你在 wallabag 上享有特权。你可以:'
388 new_user: '创建新用户'
389 analytics: '配置数据分析'
390 sharing: '启用关于文章分享的一些参数'
391 export: '配置导出选项'
392 import: '配置导入选项'
393 first_steps:
394 title: '第一步'
395 description: "既然现在已经配置好 wallabag,是时候归档一些网页了。你可以点击右上角的 + 号来保存一个链接。"
396 new_article: '保存你的第一篇文章'
397 unread_articles: '然后给它分类!'
398 migrate:
399 title: '从已有服务中转移'
400 description: "你正在使用其它服务吗?我们会帮助你将数据转移到 wallabag。"
401 pocket: '从 Pocket 转移'
402 wallabag_v1: '从 wallabag v1 转移'
403 wallabag_v2: '从 wallabag v2 转移'
404 readability: '从 Readability 转移'
405 instapaper: '从 Instapaper 转移'
406 developer:
407 title: '给开发者们'
408 description: '我们当然也考虑到了开发者们:Docker,API,翻译,等等。'
409 create_application: '创建你的第三方应用程序'
410 use_docker: '使用 Docker 来安装 wallabag'
411 docs:
412 title: '完整文档'
413 description: "wallabag 中是有如此多的功能。欢迎阅读文档来了解和学习使用它们。"
414 annotate: '标注你的文章'
415 export: '将你的文章转换成 ePUB 或者 PDF'
416 search_filters: '看看你能如何运用搜索和筛选功能来找到一篇文章'
417 fetching_errors: '当一篇文章抓取出错时,我该怎么办?'
418 all_docs: '还有另外的许多文档!'
419 support:
420 title: '支持'
421 description: '如果你需要帮助,我们在这里。'
422 github: 'GitHub 上'
423 email: '通过 email'
424 gitter: 'Gitter 上'
425
426tag:
427 page_title: '标签'
428 list:
429 number_on_the_page: '{0} 暂时没有标签。|{1} 目前有 1 个标签。|]1,Inf[ 目前有 %count% 个标签。'
430 see_untagged_entries: '查看未分配标签的项目'
431 no_untagged_entries: '目前没有未分配标签的项目。'
432 new:
433 add: '添加'
434 placeholder: '你可以添加数个标签,彼此之间用逗号分隔。'
435 rename:
436 placeholder: '你可以更新标签名称。'
437
438export:
439 footer_template: '<div style="text-align:center;"><p> 由 wallabag 通过 %method% 生成</p><p>如果该电子书在你的设备上显示有问题,请在 Github 上 <a href="https://github.com/wallabag/wallabag/issues">汇报</a>。</p></div>'
440 unknown: '未知'
441
442import:
443 page_title: '导入'
444 page_description: '欢迎来到 wallabag 导入器,请选择你想要从哪个服务导入已有内容。'
445 action:
446 import_contents: '导入内容'
447 form:
448 mark_as_read_title: '是否全部标记为已读'
449 mark_as_read_label: '将全部项目标记为已读'
450 file_label: '文件'
451 save_label: '上传文件'
452 pocket:
453 page_title: '导入 > Pocket'
454 description: "这个导入器会导入你 Pocket 账户中的所有内容。Pocket 不允许我们从它的服务器获取文章全文,所以导入的文章将由 wallabag 来重新抓取可读内容。"
455 config_missing:
456 description: "尚未配置好从 Pocket 中导入的功能。"
457 admin_message: 'You need to define %keyurls%a pocket_consumer_key%keyurle%.'
458 user_message: '你的服务器管理员需要先为 Pocket 配置一个 API Key。'
459 authorize_message: '你可以从你的 Pocket 账号中汇入数据。只需要点击下方按钮并授权该应用程序连接 getpocket.com。'
460 connect_to_pocket: '连接到 Pocket 并导入数据'
461 wallabag_v1:
462 page_title: 'Import > Wallabag v1'
463 description: '这个导入器会导入你 wallabag v1 账户中的所有文章。在你的配置页面中的"Export your wallabag data"一栏,点击"JSON export"。你就会得到一个名为"wallabag-export-1-xxxx-xx-xx.json"的文件。'
464 how_to: '请选择你的 wallabag 导出文件并点击下方按钮来上传和导入它。'
465 wallabag_v2:
466 page_title: 'Import > Wallabag v2'
467 description: '这个导入器会导入你 wallabag v2 账户中的所有文章。前往 “所有项目”,然后在“导出” 侧边栏上,点击"JSON"。 你会得到一个名为"All articles.json"的文件。'
468 elcurator:
469 page_title: 'Import > elCurator'
470 description: '这个导入器会导入你 elCurator 账户中的所有内容。前往你 elCurator 账户的偏好设置页面,然后导出你的内容。你将得到一个 JSON 文件。'
471 readability:
472 page_title: 'Import > Readability'
473 description: '这个导入器会导入你 Readability 账户中的所有内容。在 tools(https://www.readability.com/tools/)页面,点击 "Data Export" 一栏下的 "Export your data",你将会收到一封邮件,根据邮件指示下载得到一个 JSON 文件(尽管它并不以. json 结尾)。'
474 how_to: '请选择你的 Readability 导出文件并点击下方按钮来上传和导入它。'
475 worker:
476 enabled: "导入是异步进行的。一旦导入任务开始,一个外部 worker 就会一次处理一个 job。目前的服务是:"
477 download_images_warning: "你选择了为你导入的文章下载图片。这和导入流程一起进行时,可能需要非常久才能完成(甚至可能失败)。我们<strong>强烈建议</strong>启用异步导入来避免可能的错误。"
478 firefox:
479 page_title: 'Import > Firefox'
480 description: "这个导入器会导入你 Firefox 中的所有书签。只需要前往你的 bookmarks 页面(Ctrl+Maj+O),然后进入 \"Import and backup\",选择 \"Backup...\"你将得到一个 .json 文件。"
481 how_to: "请选择书签备份文件然后点击下方的按钮来导入它。请注意这一过程可能会持续一段时间,因为需要获取所有的文章。"
482 chrome:
483 page_title: 'Import > Chrome'
484 description: "这个导入器会导入你 Chrome 中的所有书签。文件的位置取决于你的操作系统: <ul><li>在 Linux 上,前往 <code>~/.config/chromium/Default/</code> 目录</li><li> 在 Windows 上,它应该位于 <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>在 OS X 上,它应该在 <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>到达对应目录后, 把 <code>Bookmarks</code> 文件复制到一个你能找到的地方。<em><br>请注意如果你使用 Chromium 而不是 Chrome,你需要对应地纠正目录。</em></p>"
485 how_to: "请选择书签备份文件然后点击下方的按钮来导入它。请注意这一过程可能会持续一段时间,因为需要获取所有的文章。"
486 instapaper:
487 page_title: 'Import > Instapaper'
488 description: '这个导入器会导入你 Instapaper 账户中的所有内容。在设置页面(https://www.instapaper.com/user),点击 "Export" 一栏下的 "Download .CSV file"。你将会下载得到一个 CSV 文件(比如"instapaper-export.csv")。'
489 how_to: '请选择你的 Instapaper 导出文件并点击下方按钮来上传和导入它。'
490 pinboard:
491 page_title: "Import > Pinboard"
492 description: '这个导入器会导入你 Pinboard 账户中的所有内容。 在 backup 页面(https://pinboard.in/settings/backup),点击 "Bookmarks" 一栏下的 "JSON"。你将会下载得到一个 JSON 文件(比如"pinboard_export")。'
493 how_to: '请选择你的 Pinboard 导出文件并点击下方按钮来上传和导入它。'
494
495developer:
496 page_title: 'API 客户端管理'
497 welcome_message: '欢迎来到 wallabag API'
498 documentation: '文档'
499 how_to_first_app: '如何创建我的第一个应用程序'
500 full_documentation: '查看完整的 API 文档'
501 list_methods: '列出 API 方法'
502 clients:
503 title: '客户端'
504 create_new: '创建一个新的客户端'
505 existing_clients:
506 title: '现有客户端'
507 field_id: 'Client ID'
508 field_secret: 'Client secret'
509 field_uris: 'Redirect URIs'
510 field_grant_types: '允许的授权形式'
511 no_client: '目前还没有客户端。'
512 remove:
513 warn_message_1: '你可以删除客户端 %name%。 请注意这一操作不可撤销!'
514 warn_message_2: "如果你删除了它,所有通过它配置的应用程序都将不再得到你的 wallabag 的授权。"
515 action: '移除客户端 %name%'
516 client:
517 page_title: 'API 客户端管理 > 新客户端'
518 page_description: '你将要创建一个新的客户端。请在以下区域中填写你应用程序的 redirect URI。'
519 form:
520 name_label: '客户端名称'
521 redirect_uris_label: 'Redirect URIs(可选)'
522 save_label: '创建新客户端'
523 action_back: '返回'
524 copy_to_clipboard: 拷贝
525 client_parameter:
526 page_title: 'API 客户端管理 > 客户端参数'
527 page_description: '以下是你客户端的参数。'
528 field_name: 'Client name'
529 field_id: 'Client ID'
530 field_secret: 'Client secret'
531 back: '返回'
532 read_howto: '阅读教程 "如何创建我的第一个应用程序" '
533 howto:
534 page_title: 'API 客户端管理 > 如何创建我的第一个应用程序'
535 description:
536 paragraph_1: '以下命令使用了 <a href="https://github.com/jkbrzt/httpie">HTTPie 库</a>。 使用前请确保你已经在系统中安装了它。'
537 paragraph_2: '你需要一个 token 来在你的第三方应用程序和 wallabag API 之间通讯。'
538 paragraph_3: '为了创建这个 token,你需要 <a href="%link%">创建一个新的客户端</a>。'
539 paragraph_4: '现在,创建你的 token(将以下 client_id,client_secret,username and password 替换为有效值):'
540 paragraph_5: 'API 将会返回一个类似下面这样的 response:'
541 paragraph_6: 'access_token 可以用于发起一个向 API 端点的请求。例如:'
542 paragraph_7: '这个请求可以返回你的用户的所有项目。'
543 paragraph_8: '如果你想要查看所有 API 端点,你可以看看<a href="%link%">我们的 API 文档</a>。'
544 back: '返回'
545
546user:
547 page_title: 用户管理
548 new_user: 创建一个新用户
549 edit_user: 编辑现有用户
550 description: "在这里你可以管理所有的用户(创建,编辑和删除)"
551 list:
552 actions: 操作
553 edit_action: 编辑
554 yes: 是
555 no: 否
556 create_new_one: 创建新用户
557 form:
558 username_label: '用户名 / 邮箱'
559 name_label: '用户名'
560 password_label: '密码'
561 repeat_new_password_label: '重新输入新密码'
562 plain_password_label: '????'
563 email_label: '邮箱'
564 enabled_label: '启用'
565 last_login_label: '上次登录'
566 twofactor_email_label: 两步验证(通过邮箱)
567 twofactor_google_label: 两步验证(通过 OTP 应用)
568 save: 保存
569 delete: 删除
570 delete_confirm: 确定要这么做吗?
571 back_to_list: 返回列表
572 search:
573 placeholder: 通过用户名或者邮箱筛选
574
575site_credential:
576 page_title: 网站登录凭证管理
577 new_site_credential: 创建一个凭证
578 edit_site_credential: 编辑一个现有凭证
579 description: "在这里你可以管理所有的登录凭证(创建,编辑和删除),有的网站可能会用它们来实施付费墙和认证功能等。"
580 list:
581 actions: 操作
582 edit_action: 编辑
583 yes: 是
584 no: 否
585 create_new_one: 创建新的凭证
586 form:
587 username_label: '登录名'
588 host_label: '主机(subdomain.example.org,.example.org,等等)'
589 password_label: '密码'
590 save: 保存
591 delete: 删除
592 delete_confirm: 确定这么做吗?
593 back_to_list: 返回列表
594
595error:
596 page_title: 发生了一个错误
597
598flashes:
599 config:
600 notice:
601 config_saved: '配置已保存。'
602 password_updated: '密码已更新'
603 password_not_updated_demo: "在演示模式下,你不能更改此用户的密码。"
604 user_updated: '信息已更新'
605 feed_updated: '订阅源信息已更新'
606 tagging_rules_updated: '标签规则已更新'
607 tagging_rules_deleted: '标签规则已删除'
608 feed_token_updated: '订阅源令牌已更新'
609 feed_token_revoked: '订阅源令牌已作废'
610 annotations_reset: 标注已重置
611 tags_reset: 标签已重置
612 entries_reset: 项目列表已重置
613 archived_reset: 所有存档项目已删除
614 otp_enabled: 两步验证已启用
615 tagging_rules_imported: 标签规则已导入
616 tagging_rules_not_imported: 导入标签规则时发生了错误
617 entry:
618 notice:
619 entry_already_saved: '该项目已于 %date% 保存'
620 entry_saved: '项目已保存'
621 entry_saved_failed: '项目已保存,但抓取内容时出现错误'
622 entry_updated: '项目已更新'
623 entry_reloaded: '项目重新抓取成功'
624 entry_reloaded_failed: '已尝试重新抓取,但抓取内容时出现错误'
625 entry_archived: '项目已存档'
626 entry_unarchived: '已将项目放回未读列表'
627 entry_starred: '项目已添加星标'
628 entry_unstarred: '已将项目移除星标'
629 entry_deleted: '项目已删除'
630 no_random_entry: '当前筛选条件下无符合项目'
631 tag:
632 notice:
633 tag_added: '标签添加成功'
634 tag_renamed: '标签重命名成功'
635 import:
636 notice:
637 failed: '导入失败,请重试。'
638 failed_on_file: '处理导入任务是出现错误,请检查你的导入文件。'
639 summary: '导入情况摘要: %imported% 个项目成功导入,%skipped% 个项目之前已保存。'
640 summary_with_queue: '导入情况摘要: %queued% 个项目正在等待导入。'
641 error:
642 redis_enabled_not_installed: 已启用 Redis 来处理异步导入任务,但我们似乎<u>无法连接到它</u>。请检查 Redis 的配置。
643 rabbit_enabled_not_installed: 已启用 RabbitMQ 来处理异步导入任务,但我们似乎<u>无法连接到它</u>。请检查 RabbitMQ 的配置。
644 developer:
645 notice:
646 client_created: '新客户端 %name% 创建成功。'
647 client_deleted: '客户端 %name% 已删除'
648 user:
649 notice:
650 added: '新用户 "%username%" 创建成功'
651 updated: '用户 "%username%" 已更新'
652 deleted: '用户 "%username%" 已删除'
653 site_credential:
654 notice:
655 added: '"%host%" 的登录凭证已添加'
656 updated: '"%host%" 的登录凭证已更新'
657 deleted: '"%host%" 的登录凭证已删除'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/validators.zh.yml b/src/Wallabag/CoreBundle/Resources/translations/validators.zh.yml
new file mode 100644
index 00000000..3541c768
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/translations/validators.zh.yml
@@ -0,0 +1,7 @@
1validator:
2 password_must_match: '两次输入的密码必须匹配。'
3 password_too_short: '密码最少需要包含 8 个字符'
4 password_wrong_value: '当前密码输入错误'
5 item_per_page_too_high: '这会让应用十分卡顿'
6 feed_limit_too_high: '这会让应用十分卡顿'
7 quote_length_too_high: '引用内容过长,最多不能超过 {{ limit }} 个字符。'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
index b747ed84..4182628f 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
@@ -96,16 +96,21 @@
96 {% if tag is defined %} 96 {% if tag is defined %}
97 {% set currentTag = tag %} 97 {% set currentTag = tag %}
98 {% endif %} 98 {% endif %}
99 {% set exportSearchTerm = null %}
100 {% if searchTerm is defined %}
101 {% set exportSearchTerm = searchTerm %}
102 {% endif %}
103 {% set previousRoute = app.request.attributes.get('currentRoute') %}
99 <h2>{{ 'entry.list.export_title'|trans }}</h2> 104 <h2>{{ 'entry.list.export_title'|trans }}</h2>
100 <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">&times;</a> 105 <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">&times;</a>
101 <ul> 106 <ul>
102 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %} 107 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">EPUB</a></li>{% endif %}
103 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %} 108 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">MOBI</a></li>{% endif %}
104 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %} 109 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">PDF</a></li>{% endif %}
105 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %} 110 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">JSON</a></li>{% endif %}
106 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %} 111 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">CSV</a></li>{% endif %}
107 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %} 112 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">TXT</a></li>{% endif %}
108 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %} 113 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">XML</a></li>{% endif %}
109 </ul> 114 </ul>
110 </aside> 115 </aside>
111 116
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
index 3906e1e0..0cd00cfd 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
@@ -39,7 +39,7 @@
39 39
40 <ul class="{% if listMode == 1 %}collection{% else %}row data{% endif %}"> 40 <ul class="{% if listMode == 1 %}collection{% else %}row data{% endif %}">
41 {% for entry in entries %} 41 {% for entry in entries %}
42 <li id="entry-{{ entry.id|e }}" class="col {% if listMode == 0 %}l3 m6{% else %}collection-item{% endif %} s12"> 42 <li id="entry-{{ entry.id|e }}" class="entry col {% if listMode == 0 %}l3 m6{% else %}collection-item{% endif %} s12">
43 {% if listMode == 1 %} 43 {% if listMode == 1 %}
44 {% include "@WallabagCore/themes/material/Entry/_card_list.html.twig" with {'entry': entry} only %} 44 {% include "@WallabagCore/themes/material/Entry/_card_list.html.twig" with {'entry': entry} only %}
45 {% elseif not entry.previewPicture is null and entry.mimetype starts with 'image/' %} 45 {% elseif not entry.previewPicture is null and entry.mimetype starts with 'image/' %}
@@ -63,15 +63,20 @@
63 {% if tag is defined %} 63 {% if tag is defined %}
64 {% set currentTag = tag.slug %} 64 {% set currentTag = tag.slug %}
65 {% endif %} 65 {% endif %}
66 {% set exportSearchTerm = null %}
67 {% if searchTerm is defined %}
68 {% set exportSearchTerm = searchTerm %}
69 {% endif %}
70 {% set previousRoute = app.request.attributes.get('currentRoute') %}
66 <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4> 71 <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4>
67 <ul> 72 <ul>
68 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %} 73 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">EPUB</a></li>{% endif %}
69 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %} 74 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">MOBI</a></li>{% endif %}
70 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %} 75 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">PDF</a></li>{% endif %}
71 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %} 76 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">JSON</a></li>{% endif %}
72 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %} 77 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">CSV</a></li>{% endif %}
73 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %} 78 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">TXT</a></li>{% endif %}
74 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %} 79 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag, 'search_entry[term]' : exportSearchTerm, 'currentRoute' : previousRoute }) }}">XML</a></li>{% endif %}
75 </ul> 80 </ul>
76 </div> 81 </div>
77 82
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.zh.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.zh.yml
new file mode 100644
index 00000000..1981e7b6
--- /dev/null
+++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.zh.yml
@@ -0,0 +1,11 @@
1# Two factor mail
2auth_code:
3 on: '启用'
4 mailer:
5 subject: 'wallabag 验证码'
6 body:
7 hello: "嗨,%user%,"
8 first_para: "因为你要求在登录到你的 wallabag 账号前需要完成两步验证,而刚刚一个新的设备请求完成该验证,为此我们给你发送了这个代码以供验证。"
9 second_para: "以下是需要用到的代码:"
10 support: "如果遇到任何问题,欢迎联系我们:"
11 signature: "wallabag 团队"