Compare commits

...

404 Commits

Author SHA1 Message Date
Elio Struyf
34c8ebd1a1 Merge pull request #627 from estruyf/dev 2023-08-21 11:57:08 +02:00
Elio Struyf
6f9d418c59 Updated readme 2023-08-21 11:56:13 +02:00
Elio Struyf
b1a7cd0300 Merge pull request #624 from estruyf/dev 2023-08-21 11:53:35 +02:00
Elio Struyf
147a1e288f Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-08-21 11:47:14 +02:00
Elio Struyf
2ee41b9f36 Fix replace 2023-08-21 11:47:08 +02:00
Elio Struyf
6a03f950cb Merge branch 'main' into dev 2023-08-21 11:35:27 +02:00
Elio Struyf
4cb1019c34 Update changelog 2023-08-21 11:33:13 +02:00
Elio Struyf
54378dd1a9 Added customType for custom fields 2023-08-21 11:29:07 +02:00
Elio Struyf
0915b1f658 Remove logs 2023-08-21 11:07:26 +02:00
Elio Struyf
5404b9d85a #591 - Fix correct date 2023-08-21 10:03:21 +02:00
Elio Struyf
cbfb5a0ba2 Update localization sync 2023-08-20 14:07:50 +02:00
Elio Struyf
4b2eef70cd Added link to release notes 2023-08-20 13:08:27 +02:00
Elio Struyf
23a48e0768 Issue: Content filter for external content not working #616 2023-08-20 11:24:03 +02:00
Elio Struyf
a9bf770f26 #621 - Create data file if it does not exist yet 2023-08-20 11:11:16 +02:00
Elio Struyf
c47bc04510 Issue: Insert media dialog is cropped on smaller screens #617 2023-08-18 11:05:12 +02:00
Elio Struyf
ad9fb70d53 #619 - Added webview URL to use for fallback images 2023-08-17 17:51:07 +02:00
Elio Struyf
7963ec0c6a Fix in description 2023-08-17 16:12:03 +02:00
Elio Struyf
79bee8fc57 #620 - use antd field logic 2023-08-16 09:49:08 +02:00
Elio Struyf
32c2e822c2 #620: Fix in array field of data files 2023-08-16 09:43:56 +02:00
Elio Struyf
4f8671ed2c #598 - fix folders and filters default value 2023-08-11 13:48:41 +02:00
Elio Struyf
598785570f #615 - Added relative option to the public folder setting 2023-08-06 15:00:31 -04:00
Elio Struyf
5ad545ae5c #615 - support for astro:assets added 2023-08-05 22:03:17 -04:00
Elio Struyf
fe7c29adbb Fix typo in reference 2023-08-04 17:10:46 -04:00
Elio Struyf
1257731209 Update panel wv to provider 2023-08-04 17:06:19 -04:00
Elio Struyf
92dfc90506 Update references 2023-08-04 16:56:44 -04:00
Elio Struyf
0fb8ba7698 Downgrade vscode version 2023-08-04 16:51:13 -04:00
Elio Struyf
74b05d6d8c Dependency updates + Panel view refactoring 2023-08-04 16:49:01 -04:00
Elio Struyf
987bfab8b4 Optimize check 2023-08-03 10:31:19 -04:00
Elio Struyf
a320ea003f Only bind the save and delete listeners once 2023-08-03 10:04:02 -04:00
Elio Struyf
c26a2692ef Update changelog 2023-07-29 14:25:09 -04:00
Elio Struyf
8e77d3662b update changelog 2023-07-29 13:27:14 -04:00
Elio Struyf
73ba8844e3 German localization added 2023-07-29 13:26:00 -04:00
Elio Struyf
14fb4d836d Update changelog 2023-07-26 19:10:21 -04:00
Elio Struyf
ad25260ddc 9.0.0 2023-07-26 19:04:10 -04:00
Elio Struyf
3fabda4bc8 Updated changelog 2023-07-26 19:03:43 -04:00
Elio Struyf
6379918f8c Merge pull request #600 from mayumih387/issue/598 2023-07-26 19:02:02 -04:00
mayumihara
f6bd6a29b0 Merge branch 'estruyf:issue/598' into issue/598 2023-07-26 15:42:51 +09:00
mayumih387
31ca2cd7c7 Created Japanese translation 2023-07-26 15:24:36 +09:00
mayumih387
ac4c7d8433 Revised URL typo 2023-07-26 15:24:02 +09:00
Elio Struyf
4a477e6589 Fix typo 2023-07-25 21:52:08 -04:00
Elio Struyf
545850392d Merge branch 'dev' into issue/598 2023-07-25 21:51:02 -04:00
Elio Struyf
5796d93b0d #611: Fix typo in the frontMatter.global.disabledNotifications setting 2023-07-25 21:49:29 -04:00
mayumihara
35ad309fd5 Merge branch 'estruyf:issue/598' into issue/598 2023-07-22 11:17:30 +09:00
Elio Struyf
8379ed8b3b Localization of commands and settings 2023-07-21 21:02:47 -04:00
mayumihara
bb6c47ac10 Merge branch 'estruyf:issue/598' into issue/598 2023-07-21 22:08:56 +09:00
Elio Struyf
8222fb3cd3 Update contentFolder 2023-07-21 08:08:25 -04:00
mayumihara
af5400d5fd Merge branch 'estruyf:issue/598' into issue/598 2023-07-20 12:09:55 +09:00
Elio Struyf
face167d56 Update sentry 2023-07-19 21:49:59 -04:00
Elio Struyf
0924a97b43 Final localization keys and values 2023-07-19 21:37:32 -04:00
Elio Struyf
4dc1016797 Update panel localization 2023-07-19 19:20:58 -04:00
Elio Struyf
31a2451482 Panel localization 2023-07-19 18:39:40 -04:00
Elio Struyf
f5abbff636 Merge branch 'dev' into issue/598 2023-07-19 17:23:41 -04:00
Elio Struyf
70f6b7261c Panel content type 2023-07-19 10:16:54 -04:00
Elio Struyf
5fa49f6d87 Localization dashboard webview 2023-07-19 10:07:31 -04:00
Elio Struyf
a4bf972b1d Localization of steps + taxonomy 2023-07-17 21:46:58 -04:00
Elio Struyf
ed8954b38a Update preview + snippets 2023-07-17 19:23:44 -04:00
Elio Struyf
b289f2d6f4 Added media localization 2023-07-17 19:07:42 -04:00
Elio Struyf
906d74626a Update localization 2023-07-17 09:59:14 -04:00
Elio Struyf
15b58181fd Added watch script + localization 2023-07-16 20:01:09 -04:00
Elio Struyf
c35dace7c7 Localization updates 2023-07-17 01:47:15 +02:00
Elio Struyf
84c647a93c Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-07-12 09:23:42 +02:00
Elio Struyf
e32813847f Issue: Can't previe index.md of hugo reaf bundle with "previewPath": "/{{pathToken.relPath}}" #603 2023-07-12 09:22:57 +02:00
Elio Struyf
6cd304f739 Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-07-11 14:20:35 +02:00
Elio Struyf
edb8bf8ff7 #602: fix for Windows paths 2023-07-11 14:20:15 +02:00
Elio Struyf
dee11aedce Slash fix 2023-07-11 14:11:17 +02:00
Elio Struyf
8d72f0845a Feedback: Hugo with partial content in modules vs. Dashboard #602 2023-07-11 10:53:08 +02:00
Elio Struyf
4b87430776 Fix hardcoded reference 2023-07-11 10:08:14 +02:00
Elio Struyf
6de325b8ec Add description AI + put theme suppor in stable mode 2023-07-10 16:42:08 +02:00
Elio Struyf
d52fabc9e9 Small css fix 2023-07-10 12:02:38 +02:00
Elio Struyf
7864e9d2b9 Add new find script 2023-07-05 13:07:28 +02:00
mayumih387
bc14b67ec1 Added translate for Actions 2023-07-04 22:47:27 +09:00
mayumih387
345ce4751f Added Japanese 2023-07-04 22:35:28 +09:00
Elio Struyf
bcc8060aa9 Update prepublish 2023-07-04 12:17:24 +02:00
Elio Struyf
c247af449a #598: Add localization support to the panel + scripts 2023-07-04 10:53:35 +02:00
Elio Struyf
71743bf292 #598: initial configuration for a multilingual UI 2023-07-03 18:47:11 +02:00
Elio Struyf
ba4f49afa2 #569 - Remove folder when using page bundle 2023-07-03 14:06:12 +02:00
Elio Struyf
bf0746d315 #599: Add a placeholder when the base panel view is empty 2023-07-02 13:32:55 +02:00
Elio Struyf
c02e02e9bd #590 - Fix in metadata parsing 2023-07-02 12:18:44 +02:00
Elio Struyf
3ec532ef17 #596 - Fix for number field in block data 2023-06-30 15:06:25 +02:00
Elio Struyf
a041d8267f Issue: Media used as fieldGroup inside a fieldGroup not working #590 2023-06-30 12:54:44 +02:00
Elio Struyf
313d2eff8c Fix styling issue 2023-06-29 17:50:41 +02:00
Elio Struyf
e6b28ce7ba #595: Fix media metadata 2023-06-29 17:13:32 +02:00
Elio Struyf
c1410de12e Enhancement: Date format in preview path #593 2023-06-29 11:43:40 +02:00
Elio Struyf
1be87875d6 update badges 2023-06-23 14:13:10 +02:00
Elio Struyf
143599bb39 #591 - Added date format support on datetime field 2023-06-22 14:51:33 +02:00
Elio Struyf
c9095caa03 #590 - Fix image update in block 2023-06-21 10:17:22 +02:00
Elio Struyf
b644cab111 process image fields in blocks 2023-06-21 09:00:47 +02:00
Elio Struyf
b799b46d08 #590 - Fix for image fields inside a sub-block 2023-06-20 15:36:00 +02:00
Elio Struyf
91d6d359d0 #588 - Added support to override card fields 2023-05-26 09:01:16 +02:00
Elio Struyf
4bf661563b Remove console 2023-05-24 15:53:20 +02:00
Elio Struyf
d641060b62 New useExtensibility hook + extensibility points 2023-05-24 15:53:02 +02:00
Elio Struyf
9e99ebf321 Remove log 2023-05-23 16:31:25 +02:00
Elio Struyf
e251a4f896 #585 - Fix empty slugs 2023-05-23 16:29:36 +02:00
Elio Struyf
a29d2a86e0 #586 - Allow to specify the content card fields 2023-05-23 15:35:58 +02:00
Elio Struyf
9515b74182 #585 - Added content relationship field 2023-05-17 13:40:12 +02:00
Elio Struyf
7a2a2004f6 #584 - Generate content type without type field 2023-05-16 13:17:05 +02:00
Elio Struyf
25ddadd5d6 #584 - Ignore type field in content-type validation 2023-05-10 14:35:43 +02:00
Elio Struyf
e18a5c082f Added customfield option to the field types 2023-05-10 14:26:03 +02:00
Elio Struyf
3a0fe7b4db Merge pull request #581 from santoshyadavdev/main 2023-05-02 10:09:23 +02:00
Santosh Yadav
b91713351e fix: correct link for data files view 2023-05-01 00:37:38 +02:00
Elio Struyf
9884bc753c #577 - Fix in the dataFile field 2023-04-26 10:43:49 +02:00
Elio Struyf
04d6bfd0df #424 - update setting 2023-04-24 09:15:34 +02:00
Elio Struyf
0effbc7b7c Merge branch 'unional-patch-1' into dev 2023-04-24 09:11:14 +02:00
Homa Wong
3166ad49cc fix: typo
This should fix the error:

```sh
$ref 'gobalconfiguration' in 'vscode://schemas/settings/configurationDefaults' can not be resolved.```
2023-04-23 21:10:53 -07:00
Elio Struyf
c5aedfffd1 Enhancement: Add ability to open snippet in modal for editing #424 2023-04-18 12:54:55 +02:00
Elio Struyf
89344aef15 #424 - Implementation of the snippet wrapper 2023-04-18 09:42:15 +02:00
Elio Struyf
d11c7e8509 #558 #573 - Fix taxonomy db creation when project is not initialized 2023-04-15 10:47:56 +02:00
Elio Struyf
5f1279eeb8 8.5.0 2023-04-14 15:54:03 +02:00
Elio Struyf
32da568025 Update version 2023-04-14 15:53:29 +02:00
Elio Struyf
628782432a #558 - Moved taxonomy to its own database file 2023-04-14 15:53:16 +02:00
Elio Struyf
28e4220b74 Fix for content updates 2023-04-14 15:11:27 +02:00
Elio Struyf
5939dccc3b update changelog 2023-04-14 13:56:11 +02:00
Elio Struyf
fd362f3787 Merge branch 'issue/566' into dev 2023-04-14 13:52:47 +02:00
Elio Struyf
055733658b #572 - fix link 2023-04-12 19:30:24 +02:00
Elio Struyf
994c7f6405 Added status and date field classes 2023-04-07 10:26:43 +02:00
Elio Struyf
58e6da0fcc Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-04-07 10:20:34 +02:00
Elio Struyf
510c982de1 #567 - Update positioning of taxonomy filters 2023-04-07 10:20:29 +02:00
Elio Struyf
e941153fa8 Update positioning of taxonomy filters 2023-04-07 10:19:19 +02:00
Elio Struyf
a84cce2f0f #568 - Update preview when slug changes 2023-04-07 10:14:10 +02:00
Elio Struyf
76126b0291 #566 - implementing persistent panel for previews 2023-04-06 19:21:56 +02:00
Elio Struyf
6f2dc2cb52 #564 - only pass strings to the taxonomy dashboard 2023-04-04 16:25:29 +02:00
Elio Struyf
4fb32bbf9e Merge pull request #560 from estruyf/dev 2023-04-03 16:48:35 +02:00
Elio Struyf
11103ad52f Updated the changelog 2023-04-03 15:57:03 +02:00
Elio Struyf
398691bace #557 - Fix for dropdown of the tag picker 2023-04-03 12:50:58 +02:00
Elio Struyf
7df731b55f Merge branch 'issue/548-projects' into dev 2023-04-02 21:29:34 +02:00
Elio Struyf
61d8d606a7 #556 #555 - better field type detection 2023-04-02 21:22:39 +02:00
Elio Struyf
f65060fc7c #523 - add default step 2023-04-01 19:18:16 +02:00
Elio Struyf
7bd77e436d #535 - fix when no image is selected 2023-04-01 15:46:49 +02:00
Elio Struyf
4b37c4c9a4 Changelog update 2023-03-31 17:01:42 +02:00
Elio Struyf
6f51e6bcd3 Update changelog 2023-03-31 16:43:13 +02:00
Elio Struyf
744e4a8fa5 Merge branch 'issue/548-projects' into dev 2023-03-31 09:16:50 +02:00
Elio Struyf
fe2a1158e2 Update chanelog 2023-03-31 09:14:52 +02:00
Elio Struyf
ecab542a65 #554 - hide media snippets 2023-03-31 09:07:41 +02:00
Elio Struyf
78f0e7f56a #548 - Project selection support 2023-03-30 21:06:04 +02:00
Elio Struyf
6bb9831542 Implementation of the project selector 2023-03-30 18:28:04 +02:00
Elio Struyf
30df5c6233 #549 - Added the folder name 2023-03-30 11:50:22 +02:00
Elio Struyf
3086ca67ce #552 - Fix for content retrieval in multi-root workspaces 2023-03-29 17:30:04 +02:00
Elio Struyf
8054a964b4 #549 - check changes in submodule 2023-03-29 08:39:41 +02:00
Elio Struyf
5336f3c9c2 #550 - Taxonomy suggestions 2023-03-28 22:41:21 +02:00
Elio Struyf
d52f51fec7 #549 - sync submodule changes 2023-03-28 20:19:32 +02:00
Elio Struyf
29479a8c05 Fix for extending array settings + card Image check 2023-03-25 11:26:45 +01:00
Elio Struyf
5d1ed08658 #513 - Add support for card image extensibility 2023-03-23 14:49:29 +01:00
Elio Struyf
e23960d9ee #547 - check for parent field 2023-03-23 12:20:52 +01:00
Elio Struyf
623878049a #547 - fix default value 2023-03-22 10:43:52 +01:00
Elio Struyf
fafe64d116 #538 - update stringify 2023-03-21 09:52:30 +01:00
Elio Struyf
9c5b8aa445 Updated name 2023-03-21 09:39:46 +01:00
Elio Struyf
5011c1c95d #538 - encodeEmoji property support 2023-03-20 13:19:32 +01:00
Elio Struyf
898f59ed6a #543 - fix json schema 2023-03-20 10:22:47 +01:00
Elio Struyf
781db743dc #528 - fix for astro files 2023-03-19 19:56:06 +01:00
Elio Struyf
a66bf12a24 #541 - rewrite the ai logic 2023-03-19 16:29:10 +01:00
Elio Struyf
5f1c835842 #541 - silent account retrieval 2023-03-19 12:13:29 +01:00
Elio Struyf
a274a34194 Update changelog 2023-03-18 21:30:11 +01:00
Elio Struyf
a958ee6fdc update changelog 2023-03-18 21:28:57 +01:00
Elio Struyf
3a5d57e03a #541 - Title suggestion AI support 2023-03-18 21:25:40 +01:00
Elio Struyf
d29d0cfc44 #512 - added frontmatter config folder support 2023-03-17 16:00:20 +01:00
Elio Struyf
f45affbd2e Merge branches 'dev' and 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-03-17 13:20:31 +01:00
Elio Struyf
6058a02b70 #512 - added jsonc file association for frontmatter.json 2023-03-17 13:12:17 +01:00
Elio Struyf
e84bf8336f #529 - fix yaml parsing in Windows 2023-03-17 12:26:31 +01:00
Elio Struyf
ea19c61b4e update settings link 2023-03-17 11:14:34 +01:00
Elio Struyf
7a901e6eba update changelog 2023-03-16 15:19:19 +01:00
Elio Struyf
48e1cd882a Added an unknown field for uniforms 2023-03-16 15:18:46 +01:00
Elio Struyf
42c44ca3a5 #539 - fix file prefix 2023-03-16 09:51:57 +01:00
Elio Struyf
b48008eb41 #537 - added support for ./ in public folder 2023-03-16 09:30:05 +01:00
Elio Struyf
bc3407fd7b #534 - move to database folder 2023-03-15 13:13:18 +01:00
Elio Struyf
143f8d799a Hover effect on images 2023-03-15 13:12:08 +01:00
Elio Struyf
73e1f21117 #535 - retain scroll position 2023-03-15 10:11:47 +01:00
Elio Struyf
92d507364e #536 - Update relative path 2023-03-15 09:02:14 +01:00
Elio Struyf
623c340f49 Removed logging 2023-03-15 08:51:15 +01:00
Elio Struyf
e661753d51 Update activation message 2023-03-15 08:51:04 +01:00
Elio Struyf
265db6f5dd #537 - Allow root path 2023-03-14 22:47:10 +01:00
Elio Struyf
1e3b4c8eaf #536 - Set the script root folder 2023-03-14 22:32:16 +01:00
Elio Struyf
f583ab2f97 #363 - Update labelfield 2023-03-14 17:21:19 +01:00
Elio Struyf
35d87226f6 Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-03-14 08:38:59 +01:00
Elio Struyf
fccffa4ea2 #363 - Multiline support 2023-03-14 08:38:37 +01:00
Elio Struyf
22dbf4681f Removed app insights + custom metrics 2023-03-13 12:45:05 +01:00
Elio Struyf
56deb432fd Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-03-13 08:56:43 +01:00
Elio Struyf
b9e46d551e #531 - fix list items 2023-03-13 08:56:37 +01:00
Elio Struyf
605ebc6a37 Set chatbot to experimental for better styling 2023-03-11 11:32:37 +01:00
Elio Struyf
c159d8037c #530 - Loading message added 2023-03-10 16:37:11 +01:00
Elio Struyf
b3a1628b77 #530 - Chatbot API update 2023-03-10 11:54:11 +01:00
Elio Struyf
5a56577695 Merge branch 'poc/ai' into dev 2023-03-09 21:06:25 +01:00
Elio Struyf
36a903c7b6 #530 - Front Matter AI 2023-03-09 21:06:13 +01:00
Elio Struyf
ecacba53a7 Added chatbot integration 2023-03-09 18:09:18 +01:00
Elio Struyf
94819cef62 #521 - fix snippets placeholder 2023-03-07 15:32:08 +01:00
Elio Struyf
14515e4f59 #526 - Fix content menu 2023-03-07 15:14:15 +01:00
Elio Struyf
53dd1303dc #518 - revert and update yaml parser + config 2023-03-06 10:46:23 +01:00
Elio Struyf
0ee4ed9e3c Merge branches 'dev' and 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-03-06 10:19:03 +01:00
Elio Struyf
9a2b0cb005 Update changelog date 2023-03-06 10:15:42 +01:00
Elio Struyf
9f11b94c60 #520 - Add url protocol 2023-03-04 12:11:42 +01:00
Elio Struyf
34f5e9c41b #523 - number options 2023-03-04 11:59:39 +01:00
Elio Struyf
ced176adad #524 - Remove global settings 2023-03-04 11:13:41 +01:00
Elio Struyf
f2c8c0a8d6 Added default servers for frameworks 2023-03-04 10:48:36 +01:00
Elio Struyf
6f45277b49 #522 - Add Astro support 2023-03-04 10:45:18 +01:00
Elio Struyf
541e02e72c Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-03-02 21:23:02 +01:00
Elio Struyf
cae62232c6 Fix panel alignment 2023-03-02 21:22:41 +01:00
Elio Struyf
8a2ee4c82c Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2023-03-02 11:51:18 +01:00
Elio Struyf
4ffcd76aac Remove log 2023-03-02 11:51:05 +01:00
Elio Struyf
3b0ea3132c #518: Fix YAML parser 2023-03-02 11:50:24 +01:00
Elio Struyf
cf29121bc0 Fix isDevelopment check 2023-02-28 19:33:57 +01:00
Elio Struyf
cbeda07d25 #513 - Added devtools command 2023-02-28 14:45:18 +01:00
Elio Struyf
8bc63a48a0 #513 - devmode for ext 2023-02-28 12:49:03 +01:00
Elio Struyf
026bcd0a84 #513 - support for custom field + panel view 2023-02-27 17:37:16 +01:00
Elio Struyf
cf6133b143 8.4.0 2023-02-26 15:38:50 +01:00
Elio Struyf
872487db4a Added the UI scripts to experimental features 2023-02-26 15:38:38 +01:00
Elio Struyf
386bf0218d Added external script loading 2023-02-26 15:18:57 +01:00
Elio Struyf
ecca570e30 Extensibility script solution 2023-02-24 19:11:31 +01:00
Elio Struyf
7e398d206a POC of rendering custom HTML 2023-02-24 18:21:12 +01:00
Elio Struyf
75af200108 Update submenu 2023-02-19 14:56:31 +01:00
Elio Struyf
d364bde59d Merge pull request #507 from estruyf/dev 2023-02-14 16:37:29 +01:00
Elio Struyf
8ae105fd6e Fixes in preview paths 2023-02-14 16:12:39 +01:00
Elio Struyf
3a8854b060 update changelog 2023-02-13 19:58:07 +01:00
Elio Struyf
af393bbfc5 #425 - fix for global file path 2023-02-12 13:23:20 +01:00
Elio Struyf
76707b9eee Update changelog 2023-02-11 15:55:00 +01:00
Elio Struyf
8042a25fbb Update changelog 2023-02-11 13:18:40 +01:00
Elio Struyf
1a3520833b #506 - added default filename 2023-02-11 12:08:58 +01:00
Elio Struyf
1b1eac0a43 Merge branch 'furkanb-issue/#504' into dev 2023-02-11 12:08:04 +01:00
furkanb
6b19e69806 sanitize defaultFileName 2023-02-11 01:55:07 +03:00
furkanb
04960b7fdb issue/#504 2023-02-11 01:47:03 +03:00
Elio Struyf
3ca979bea9 updated changelog 2023-02-10 14:58:12 +01:00
Elio Struyf
12ecee8c49 Fix address bar of preview 2023-02-10 14:53:23 +01:00
Elio Struyf
680ea99f05 #425 - Added content type check 2023-02-10 14:44:25 +01:00
Elio Struyf
39cee294af #425 - Preview questions when folder is not found 2023-02-10 14:24:14 +01:00
Elio Struyf
558845a8d2 #425 - added new placeholders for previews 2023-02-10 13:24:59 +01:00
Elio Struyf
327559fdd7 #425 - support added for placeholders in the page folders path 2023-02-09 22:30:36 +01:00
Elio Struyf
2efbfa7820 Add button border to align with VSCode 2023-02-09 21:27:30 +01:00
Elio Struyf
cdeaa87321 #480 - Updating add missing fields label 2023-02-09 21:14:40 +01:00
Elio Struyf
483cfcd761 #505 - Small theming fixes 2023-02-09 17:35:16 +01:00
Elio Struyf
74bc8d78a0 #505 - Enhancements to theming of the data fields 2023-02-09 17:24:42 +01:00
Elio Struyf
bc88df98ee #505 - Data view theming 2023-02-09 13:32:34 +01:00
Elio Struyf
d48e63ba32 Restructuring components 2023-02-09 11:28:22 +01:00
Elio Struyf
20ee0e1ca5 #505 - Step + welcome view colors 2023-02-08 19:27:48 +01:00
Elio Struyf
716f7d1f0c #505 - Preview theming 2023-02-07 20:32:23 +01:00
Elio Struyf
5119f631f3 Enhancement: VS Code theme support for the dashboards #505 2023-02-07 19:59:46 +01:00
Elio Struyf
4eea855d0f #505 - Header theming 2023-02-07 17:47:07 +01:00
Elio Struyf
5354619283 #505 - Theming for snippets view 2023-02-07 13:49:05 +01:00
Elio Struyf
dd939f4b7a #505 - Media folder items styling 2023-02-07 10:48:19 +01:00
Elio Struyf
2635cc9b6d #505 - Media dashboard theming WIP 2023-02-07 10:32:01 +01:00
Elio Struyf
c843e74077 #505 - Align to theme colors WIP 2023-02-06 18:26:11 +01:00
Elio Struyf
baed139cc6 Implement new scoped groups from tailwind 2023-02-05 14:39:28 +01:00
Elio Struyf
38839470ac #502 - Keyboard bindings added 2023-02-05 14:31:25 +01:00
Elio Struyf
8a4b24396c #503: Allow making changes to preview URL + tailwind v3 update 2023-02-05 14:13:43 +01:00
Elio Struyf
4a50cf70a0 #473 - Allow setting the SEO title name 2023-02-04 10:08:25 +01:00
Elio Struyf
db38b9da68 #488 - Create the .frontmatter folder on initialization, not before 2023-02-02 21:06:20 +01:00
Elio Struyf
2b7f124582 #496 - Move to file storage for larger states 2023-02-02 18:46:50 +01:00
Elio Struyf
089f0a643d Merge pull request #500 from pongstr/dev 2023-02-02 12:11:15 +01:00
Pongstr
9c9102f6f5 chore(devx-improvements): Deps upgrades + Prettier 2023-02-02 11:13:55 +02:00
Elio Struyf
c95d79a218 Merge pull request #499 from pongstr/devx-improvements 2023-02-01 15:17:16 +01:00
Pongstr
c0b1e4383f init: sync with dev 2023-02-01 16:13:57 +02:00
Pongstr
ddf2873794 init 2023-02-01 11:58:31 +02:00
Pongstr
faf629cca5 init 2023-02-01 11:40:12 +02:00
Elio Struyf
bf4b66564c #497 - Support for movie media added 2023-01-30 10:19:05 +01:00
Elio Struyf
5c62255605 #494 - Support added for remote images as previews 2023-01-30 10:11:06 +01:00
Elio Struyf
4f91aeb80b Update wf name 2023-01-24 10:52:00 +01:00
Elio Struyf
e19b4d7d6c #493 - fix issue with custom placeholders 2023-01-24 10:44:16 +01:00
Elio Struyf
7f02fe34ba Update labels flow 2023-01-09 13:41:21 +01:00
Elio Struyf
5dec859849 Merge branch 'main' into dev 2023-01-07 20:18:57 +01:00
Elio Struyf
5e1558ecfa Update labeling 2023-01-07 20:18:45 +01:00
Elio Struyf
8a099de859 Updated vsce dependency 2022-12-24 09:47:13 +01:00
Elio Struyf
ddef00726b update badges 2022-12-24 09:42:40 +01:00
Elio Struyf
70316c4c28 #474 - Allow to define the file prefix on content types 2022-12-23 15:00:49 +01:00
Elio Struyf
50f2e7ea72 Update readme 2022-12-23 12:12:27 +01:00
Elio Struyf
663d346e2e Temporarily remove badges 2022-12-23 12:07:26 +01:00
Elio Struyf
d42561fbf5 #469 - Fix for using the root folder as content folder 2022-12-23 12:02:49 +01:00
Elio Struyf
0c5224b5f9 Update changelog 2022-12-23 10:27:39 +01:00
Elio Struyf
cfa805add9 #407 - support for external config files 2022-12-23 10:26:20 +01:00
Elio Struyf
86a8ef68b6 Settings override 2022-12-22 21:04:24 +01:00
Elio Struyf
cc2c6dc217 Allow external configurations - start 2022-12-22 18:03:04 +01:00
Elio Struyf
1764965aa7 8.3.0 2022-12-14 10:18:22 +01:00
Elio Struyf
12559bae4a #482 - Default content type description update 2022-12-14 10:17:47 +01:00
Elio Struyf
fc1d750c5e #470 - Fix initialize project dashboard description 2022-12-14 09:45:17 +01:00
Elio Struyf
85c4a869e3 #484 - Workspace path update 2022-12-14 09:40:32 +01:00
Elio Struyf
8b3889f997 #484 - validate if command is available 2022-12-14 09:00:53 +01:00
Elio Struyf
75b01cde7b #484 - Script support for different environments 2022-12-13 12:00:01 +01:00
Elio Struyf
c75ab2a07b Update sponsor 2022-12-12 09:02:14 +01:00
Elio Struyf
a12cf70a80 Merge pull request #477 from estruyf/dev 2022-12-08 18:12:53 +01:00
Elio Struyf
4b1d80f04b Prepare v8.2.0 release 2022-12-08 18:08:58 +01:00
Elio Struyf
a84fecaf96 Update json schema + changelog 2022-12-08 16:46:45 +01:00
Elio Struyf
5b9c279fa2 #471 - Fix typo 2022-12-02 11:49:56 +01:00
Elio Struyf
f67be9efb9 update changelog 2022-11-24 17:26:22 +01:00
Elio Struyf
4c50100230 Merge pull request #466 from albbus-stack/git-deleted-files-fix
Thank you @albbus-stack!
2022-11-24 17:25:01 +01:00
albbus-stack
82ace03692 Added git deleted files in the push method 2022-11-24 14:24:09 +01:00
Elio Struyf
576d07fdef Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2022-11-14 19:40:42 +01:00
Elio Struyf
f6bc4fb630 #365 - conditional support 2022-11-14 19:40:38 +01:00
Elio Struyf
c35f4ab070 Merge branch 'issue/362-ui' into dev 2022-11-14 19:39:11 +01:00
Elio Struyf
59cbc03b0c #458 - Add prefix to page bundles 2022-11-14 10:48:15 +01:00
Elio Struyf
0ea06a841e #412 - script splitting fix 2022-11-14 10:40:52 +01:00
Elio Struyf
b54eb5a360 #462 - Fix issue in script error notification 2022-11-14 10:40:30 +01:00
Elio Struyf
16b6fff6dc #362 - Case sensitive + insensitive option 2022-11-13 20:21:47 +01:00
Elio Struyf
7a46729a46 #362 - additional operators 2022-11-12 18:11:24 +01:00
Elio Struyf
32182c3df0 #362 - Start on conditional ui 2022-11-10 17:21:16 +01:00
Elio Struyf
78587509b3 Update readme 2022-11-09 13:59:19 +01:00
Elio Struyf
e3bd7eebbe #360 - Define which content types can be used on your page folders 2022-11-09 13:59:14 +01:00
Elio Struyf
f1a8e0d425 #458 - Ability to configure the file prefix on folder level 2022-11-09 10:31:49 +01:00
Elio Struyf
33e294d702 #455 - Show a description for the SEO section 2022-11-08 11:51:41 +01:00
Elio Struyf
e098442eaa #412 - Allow title on snippets 2022-11-07 17:28:40 +01:00
Elio Struyf
1de14122c5 #440 - Filter on description 2022-11-07 15:59:20 +01:00
Elio Struyf
c0838fffd4 #448 - Full workspace path replacement 2022-11-07 10:50:01 +01:00
Elio Struyf
082c25144f #448 - Fix file retrieval 2022-11-05 18:29:47 +01:00
Elio Struyf
d701651a05 #440 - Type to search/filter in the snippets dashboard 2022-11-04 15:25:00 +01:00
Elio Struyf
5205b2d079 #450 - Additional date placeholders 2022-11-04 10:34:46 +01:00
Elio Struyf
e864d56081 #447 - Allow to use placeholders on git commit messages 2022-11-04 10:33:23 +01:00
Elio Struyf
c6a4c239a0 #449 - Show filename if the title is not set 2022-11-04 09:58:54 +01:00
Elio Struyf
42fbdf9708 #412 - Support for sub-folders 2022-10-31 09:59:33 +01:00
Elio Struyf
8d53990aea #430 - support for post_asset_folder folder 2022-10-08 17:33:42 +02:00
Elio Struyf
b9a0c656d3 async updates for settings 2022-10-07 13:32:49 +02:00
Elio Struyf
8a8db67e82 #427 - Add hexo as SSG option 2022-10-07 13:32:42 +02:00
Elio Struyf
0ac4571859 Merge branch 'issue/431' into dev 2022-10-07 10:38:55 +02:00
Elio Struyf
a072957793 Updated exists to async 2022-10-06 21:49:53 +02:00
Elio Struyf
fad5ad7243 Moving away from fs sync methods 2022-10-06 21:36:51 +02:00
Elio Struyf
b248ee7184 Merge branch 'release/v8.1.2' into dev 2022-10-06 14:49:17 +02:00
Elio Struyf
cf2d170d6f Merge pull request #437 from estruyf/release/v8.1.2 2022-10-06 14:47:13 +02:00
Elio Struyf
8d577ceb79 #435 #436 - fixes 2022-10-06 14:42:43 +02:00
Elio Struyf
5748aa0540 8.1.2 2022-10-06 14:38:37 +02:00
Elio Struyf
4e850e5cb9 Fix field error message color 2022-10-06 14:23:49 +02:00
Elio Struyf
f89d4fce3f #431 - Update changelog 2022-10-04 17:05:04 +02:00
Elio Struyf
1ecf75ae9c Merge branch 'issue/431' into dev 2022-10-04 17:00:48 +02:00
Elio Struyf
888e5c5229 Get webview URI for Windows 2022-10-04 13:47:41 +02:00
Elio Struyf
45eb542619 #431 - Allow pagination page nr 2022-10-03 21:31:23 +02:00
Elio Struyf
5a565f1154 #412 - Override duplicates in config split 2022-10-03 14:07:14 +02:00
Elio Struyf
78002563be Clear cache command 2022-10-03 13:22:40 +02:00
Elio Struyf
be3071dc18 Merge branch 'dev' into issue/431 2022-10-02 20:18:46 +02:00
Elio Struyf
5c9d7eda17 #433 - fix title and description rendering if not string 2022-10-02 20:01:59 +02:00
Elio Struyf
9f3cfd9d3a #434 - Webview errors are logged in the extension output 2022-10-02 14:26:22 +02:00
Elio Struyf
0c6ae47a7b #434 - Webview errors are logged in the extension output 2022-10-02 14:25:11 +02:00
Elio Struyf
726a26850d #431 - Cache changes + Tab navigation 2022-10-02 14:23:51 +02:00
Elio Struyf
5fbb05f083 #431 - Performance improvements for first load 2022-10-01 20:30:18 +02:00
Elio Struyf
afca99b53a Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2022-10-01 10:36:34 +02:00
Elio Struyf
a8d2c428bc #428 - Image inserting UX enhancement 2022-10-01 10:36:29 +02:00
Elio Struyf
5254f2b7f9 #412 Support added for data files and custom scripts 2022-09-30 14:44:07 +02:00
Elio Struyf
13a71cfd82 #412 - Update setting casing 2022-09-30 10:44:14 +02:00
Elio Struyf
07d67bf881 #412 - allow config folders to use lowercase 2022-09-30 09:54:55 +02:00
Elio Struyf
27887bedef #412 - splitting configuration files 2022-09-29 20:36:02 +02:00
Elio Struyf
2b8f08c03c #406 - Single data entries 2022-09-27 13:16:44 +02:00
Elio Struyf
cb2194bc48 8.2.0 2022-09-27 12:04:50 +02:00
Elio Struyf
46872f81ac Include CMS in the display name 2022-09-27 09:00:14 +02:00
Elio Struyf
eb9984396b Merge pull request #423 from estruyf/dev 2022-09-23 12:47:54 +02:00
Elio Struyf
b7b79024e1 8.1.1 2022-09-23 12:44:18 +02:00
Elio Struyf
d17cc901ff #422 - Fix panel initialization logic 2022-09-23 09:20:59 +02:00
Elio Struyf
1fe03197e3 Merge pull request #421 from estruyf/dev 2022-09-22 13:43:18 +02:00
Elio Struyf
a1eaa5baca Updated changelog for v8.1.0 2022-09-22 11:49:15 +02:00
Elio Struyf
b83b2205c0 Fix issue in image field with required message 2022-09-21 09:55:57 +02:00
Elio Struyf
989d20c474 #417 - New hyperlink wysiwyg option 2022-09-19 10:40:15 +02:00
Elio Struyf
2cf3ff93c5 #418 - Heading and divider fields 2022-09-19 10:18:41 +02:00
Elio Struyf
67b44dce42 #369 - taxonomy fix 2022-09-19 09:52:02 +02:00
Elio Struyf
c182a67daa Remove logging 2022-09-19 09:45:02 +02:00
Elio Struyf
2494e4c6c5 #369 - Notification fix 2022-09-19 09:43:57 +02:00
Elio Struyf
efc230f81e #391 - New description property 2022-09-16 16:47:32 +02:00
Elio Struyf
e455fa764b #369 - required fields 2022-09-15 11:13:26 +02:00
Elio Struyf
c6273fa9c1 #408 - add missing view mode 2022-09-12 10:38:53 +02:00
Elio Struyf
9f37ff773e #395: Media snippet enhancements 2022-09-09 18:01:55 +02:00
Elio Struyf
9b21e15c63 #402: Custom sorting of content now supports number fields 2022-09-09 16:44:37 +02:00
Elio Struyf
fe41d9a751 Remove bold version 2022-09-09 13:32:55 +02:00
Elio Struyf
5e91a0e7af Update version 2022-09-09 13:26:39 +02:00
Elio Struyf
e00186890c Update beta script 2022-09-09 13:22:36 +02:00
Elio Struyf
b2b017efc0 #404: Ordering of snippet fields is based on their field definition 2022-09-08 21:08:46 +02:00
Elio Struyf
51b11b66ab #403: Fix for media files with spaces on importing in article content 2022-09-08 20:59:50 +02:00
Elio Struyf
2275c1b9cc #401 - Enable paging on the content dashboard 2022-09-08 11:38:45 +02:00
Elio Struyf
bf98ff9a1d Disable popper 2022-09-08 11:01:29 +02:00
Elio Struyf
23c5a7bc18 #400: Fix for draft/published grouping 2022-09-08 10:44:07 +02:00
Elio
4d05c660c8 #398: Fix Windows folder path parsing in data folder retrieval 2022-09-08 10:00:38 +02:00
Elio Struyf
83d4427c09 New titles for inputs 2022-09-07 14:50:21 +02:00
Elio Struyf
45285d3cf2 8.1.0 2022-09-07 12:29:02 +02:00
Elio Struyf
f46fdb9fb0 Preview tab title 2022-09-07 10:03:25 +02:00
Elio Struyf
3557360297 #396 - Fix for index and _index previews 2022-09-07 09:59:27 +02:00
Elio Struyf
600c225265 Added divider between action buttons and custom ones 2022-09-07 08:48:14 +02:00
Elio Struyf
7fa814ca1b Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2022-09-05 15:00:33 +02:00
Elio
e4f44def47 Update changelog 2022-09-05 14:58:06 +02:00
Elio
08aa73f9c3 Merge branch 'dev' of https://github.com/estruyf/vscode-front-matter into dev 2022-09-05 14:57:27 +02:00
Elio
fcb564b054 #393 - Fix Windows file path 2022-09-05 14:55:34 +02:00
Elio Struyf
ac4aea68eb #352: Schema updates 2022-09-05 14:25:59 +02:00
Elio Struyf
ad6c37f62d Audit fix for dependencies 2022-09-05 10:55:38 +02:00
Elio Struyf
bc3d5cb6b2 Added contact links for issues 2022-09-05 10:53:57 +02:00
Elio Struyf
88c8cc82c8 #394: Ordering of snippet fields is based on their field definition 2022-09-05 10:37:30 +02:00
Elio Struyf
69e0dc3343 Hide the initialize project action 2022-09-02 13:44:11 +02:00
Elio Struyf
dda9b88752 #388: Added a stop server action 2022-09-02 13:42:50 +02:00
Elio Struyf
5b712e64d7 #390: Implement another JSON parser 2022-09-02 13:26:25 +02:00
Elio Struyf
af1cc15d3d Fix for new popper menu on media items 2022-09-02 09:50:09 +02:00
Elio Struyf
76e3c08405 Fix for custom placeholders that return errors 2022-09-02 09:49:48 +02:00
Elio Struyf
ebae16f724 Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2022-08-11 20:58:32 +02:00
Elio Struyf
911adaa5d6 #383: Add the item menu to the content list view 2022-08-11 20:56:07 +02:00
Elio Struyf
1766c19133 #385: Add a default draft field value 2022-08-11 17:52:36 +02:00
Elio Struyf
4a8bbaf82e Fix for empty tags 2022-08-11 17:43:07 +02:00
Elio Struyf
fa7b9f3ad1 Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2022-08-10 16:09:36 +02:00
Elio Struyf
ecc9c74091 #384: Fix issue title field in sub-fields 2022-08-10 16:09:21 +02:00
Elio Struyf
282c95be29 Initialize listeners 2022-08-04 21:33:00 +02:00
Elio Struyf
9325ce3638 Keep track of all config listeners 2022-08-04 21:32:30 +02:00
Elio Struyf
a4da46ca21 #379 - New frontMatter.config.reload command 2022-08-04 21:29:21 +02:00
Elio Struyf
44f30f70d5 Update authenticate command 2022-08-04 20:58:45 +02:00
Elio Struyf
2ef39cb2ed Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2022-08-04 15:23:50 +02:00
Elio Struyf
c8ecc92309 #376: post script functionality 2022-08-04 15:23:41 +02:00
Elio Struyf
3ca6609ace #377 - Git sync command 2022-07-30 14:23:57 +02:00
Elio Struyf
670791fcf6 #377 - update setting name 2022-07-29 16:16:38 +02:00
Elio Struyf
30dc33a859 #377: Git sync actions added on panel and content dashboard 2022-07-29 16:13:46 +02:00
Elio Struyf
07ed95793c #378 - Last modified update only to content in content folders 2022-07-28 11:36:26 +02:00
Elio Struyf
9a9ec33f9f Sorting fix 2022-07-27 12:08:39 +02:00
Elio Struyf
89aab6c74e #352 - Added notification + progress notification 2022-07-27 11:56:51 +02:00
Elio Struyf
c0e6c79c67 qna link 2022-07-22 16:03:45 +03:00
Elio Struyf
7badfda41b #352 - Custom placeholders now support scripting 2022-07-21 18:38:53 +03:00
Elio Struyf
9445ce6d37 #374 - Auto-fold the front matter section 2022-07-21 13:15:49 +03:00
Elio Struyf
1aa8f77590 #370 - updated JSON schema 2022-07-20 15:00:17 +03:00
Elio Struyf
dab6a46d98 #372 - Update taxonomy to taxonomies 2022-07-18 17:30:19 +03:00
Elio Struyf
6b940e2f24 Merge branch 'main' into dev 2022-07-18 17:27:06 +03:00
Elio Struyf
8c0ce05133 Hide settings icon 2022-07-17 08:13:51 +02:00
Elio Struyf
937494f81c Hide open settings + new docs and settings link 2022-07-17 08:13:42 +02:00
508 changed files with 47832 additions and 19916 deletions

17
.eslintrc.json Normal file
View File

@@ -0,0 +1,17 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"ignorePatterns": ["./**/*.js", "./webpack/*.config.js", "./e2e/*.ts"],
"rules": {
"no-throw-literal": "error",
"no-unused-expressions": "error",
"curly": "error",
"class-methods-use-this": "warn"
}
}

View File

@@ -0,0 +1 @@
{}

14
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: Documentation
url: https://frontmatter.codes/docs
about: See our documentation.
- name: Changelog
url: https://frontmatter.codes/updates
about: See our changelog.
- name: Front Matter website
url: https://frontmatter.codes
about: Our website.
- name: Support Front Matter
url: https://github.com/sponsors/estruyf
about: Support Front Matter development.

View File

@@ -43,7 +43,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -54,7 +54,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -68,4 +68,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2

View File

@@ -5,8 +5,12 @@ on:
types: [created, moved, deleted]
jobs:
automate-issues-labels:
process-project:
name: Add/remove the project label and set the matrix variable
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.setMatrixData.outputs.matrix }}
statusLabel: ${{ steps.setStatusLabel.outputs.statusLabel }}
steps:
- name: Fetch project data
run: |
@@ -14,6 +18,7 @@ jobs:
curl --request GET --url '${{ github.event.project_card.project_url }}' --header 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
### Add or remove the project label ###
- name: Add the project label
uses: andymckay/labeler@master
if: ${{ contains(github.event.action, 'created') || contains(github.event.action, 'moved') }}
@@ -24,4 +29,62 @@ jobs:
uses: andymckay/labeler@master
if: ${{ contains(github.event.action, 'deleted') }}
with:
remove-labels: "Project: ${{ fromJSON(env.PROJECT_DATA).name }}"
remove-labels: "Project: ${{ fromJSON(env.PROJECT_DATA).name }}"
### Fetch project columns ###
- name: Fetch all columns
run: |
echo 'ALL_COLUMNS_DATA<<EOF' >> $GITHUB_ENV
curl --request GET --url '${{ fromJSON(env.PROJECT_DATA).columns_url }}' --header 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' | jq --compact-output '["Status: " + .[].name]' >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- name: Fetch column info
run: |
echo 'COLUMN_DATA<<EOF' >> $GITHUB_ENV
curl --request GET --url '${{ github.event.project_card.column_url }}' --header 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- uses: actions/github-script@v6
id: setMatrixData
with:
result-encoding: string
script: |
const columnData = JSON.parse(process.env.COLUMN_DATA)
const allColumnsData = JSON.parse(process.env.ALL_COLUMNS_DATA)
const matrix = allColumnsData.filter((label) => {
return label !== `Status: ${columnData.name}`
});
core.setOutput('matrix', matrix)
- name: Set the status label
id: setStatusLabel
run: |
echo "statusLabel=${{ fromJSON(env.COLUMN_DATA).name }}" >> $GITHUB_OUTPUT
remove-labels:
runs-on: ubuntu-latest
needs: process-project
if: ${{ contains(github.event.action, 'deleted') || contains(github.event.action, 'moved') }}
strategy:
matrix:
label: ${{fromJson(needs.process-project.outputs.matrix)}}
steps:
- name: Remove the status label
uses: andymckay/labeler@master
with:
remove-labels: ${{ matrix.label }}
add-labels:
runs-on: ubuntu-latest
needs:
- process-project
- remove-labels
if: ${{ contains(github.event.action, 'created') || contains(github.event.action, 'moved') }}
steps:
- name: Add the status label
uses: andymckay/labeler@master
with:
add-labels: "Status: ${{ needs.process-project.outputs.statusLabel }}"

View File

@@ -24,7 +24,7 @@ jobs:
run: node scripts/beta-release.js $GITHUB_RUN_ID
- name: Publish
run: npx vsce publish -p ${{ secrets.VSCE_PAT }} --baseImagesUrl https://raw.githubusercontent.com/estruyf/vscode-front-matter/dev
run: npx @vscode/vsce publish -p ${{ secrets.VSCE_PAT }} --baseImagesUrl https://raw.githubusercontent.com/estruyf/vscode-front-matter/dev
- name: Publish to open-vsx.org
run: npx ovsx publish -p ${{ secrets.OPEN_VSX_PAT }}

View File

@@ -24,7 +24,7 @@ jobs:
run: node scripts/main-release.js
- name: Publish
run: npx vsce publish -p ${{ secrets.VSCE_PAT }}
run: npx @vscode/vsce publish -p ${{ secrets.VSCE_PAT }}
- name: Publish to open-vsx.org
run: npx ovsx publish -p ${{ secrets.OPEN_VSX_PAT }}

3
.gitignore vendored
View File

@@ -9,3 +9,6 @@ todo.md
e2e/storage
e2e/extensions
e2e/sample
localization.log
localization.md

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
auto-install-peers = true

7
.prettierrc Normal file
View File

@@ -0,0 +1,7 @@
{
"printWidth": 100,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"trailingComma": "none"
}

View File

@@ -1,8 +1,5 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"ms-vscode.vscode-typescript-tslint-plugin",
"eliostruyf.vscode-typescript-exportallmodules"
]
}
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": ["eliostruyf.vscode-typescript-exportallmodules", "esbenp.prettier-vscode"]
}

42
.vscode/launch.json vendored
View File

@@ -3,32 +3,24 @@
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Extension",
"version": "0.2.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "npm: build:ext"
},
{
"name": "Attach Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "npm: build:ext"
},
{
"name": "Attach Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
]
}
]
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]
}

View File

@@ -1,7 +1,7 @@
{
"Recoil Atom": {
"prefix": "sq-atom",
"body": [
"Recoil Atom": {
"prefix": "sq-atom",
"body": [
"import { atom } from 'recoil';",
"",
"export const ${1:CollectionId}Atom = atom({",
@@ -12,9 +12,9 @@
"description": "Creates a new atom",
"scope": "typescript"
},
"Recoil Selector (sync)": {
"prefix": "sq-selector-sync",
"body": [
"Recoil Selector (sync)": {
"prefix": "sq-selector-sync",
"body": [
"import { selector } from 'recoil';",
"",
"export const ${1:CollectionData}Selector = selector({",
@@ -27,9 +27,9 @@
"description": "Creates a new synchronous selector",
"scope": "typescript"
},
"Recoil Selector (async)": {
"prefix": "sq-selector-async",
"body": [
"Recoil Selector (async)": {
"prefix": "sq-selector-async",
"body": [
"import { selector } from 'recoil';",
"",
"export const ${1:CollectionData}Selector = selector({",
@@ -42,9 +42,9 @@
"description": "Creates a new asynchronous selector",
"scope": "typescript"
},
"Recoil selectorFamily": {
"prefix": "sq-selector-fam",
"body": [
"Recoil selectorFamily": {
"prefix": "sq-selector-fam",
"body": [
"import { selectorFamily } from 'recoil';",
"",
"export const ${1:CollectionData}Selector = selectorFamily({",
@@ -63,4 +63,4 @@
"description": "Include the translations",
"scope": "typescriptreact"
}
}
}

57
.vscode/settings.json vendored
View File

@@ -1,13 +1,52 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off",
"eliostruyf.writingstyleguide.terms.isDisabled": true,
"eliostruyf.writingstyleguide.biasFree.isDisabled": true,
"squarl.groups": [
{
"id": "dashboard",
"name": "Dashboard"
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
{
"id": "panel",
"name": "Panel"
}
],
"squarl.bookmarks": [
{
"name": "App.tsx",
"path": "src/dashboardWebView/components/App.tsx",
"description": "Start of dashboard",
"type": "file",
"groupId": "dashboard"
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off",
"eliostruyf.writingstyleguide.terms.isDisabled": true,
"eliostruyf.writingstyleguide.biasFree.isDisabled": true,
}
{
"name": "ViewPanel.tsx",
"path": "src/panelWebView/ViewPanel.tsx",
"description": "Start of panel",
"type": "file",
"groupId": "panel"
},
{
"name": "styles.css",
"path": "src/panelWebView/styles.css",
"description": "Panel styles",
"type": "file",
"groupId": "panel"
},
{
"name": "settings.ts",
"path": "src/constants/settings.ts",
"description": "Settings names",
"type": "file"
}
]
}

48
.vscode/tasks.json vendored
View File

@@ -1,28 +1,28 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "npm",
"script": "build:ext",
"group": {
"kind": "build",
"isDefault": true
}
}
]
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "npm",
"script": "build:ext",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

View File

@@ -5,7 +5,6 @@ src/**
.gitignore
vsc-extension-quickstart.md
**/tsconfig.json
**/tslint.json
**/*.map
**/*.ts
webpack.config.js
@@ -28,4 +27,4 @@ frontmatter.json
webpack
README.beta.md
e2e
storage
storage

View File

@@ -1,5 +1,253 @@
# Change Log
## [9.0.0] - 2023-08-21 - [Release notes](https://beta.frontmatter.codes/updates/v9.0.0)
### 🌎 Multilingual support
- German (translated via OpenAI)
- Japanese (thanks to [mayumihara](https://github.com/mayumih387))
### 🧪 Experimental features
- External UI script support for dashboards and Front Matter panel
- Front matter AI 🤖
> **Info**: To enable the experimental features you need to set the `frontMatter.experimental` setting to `true`.
### ✨ New features
- Added description AI suggestion for GitHub sponsors
- The Visual Studio Code theme support is now released in the stable version
- [#424](https://github.com/estruyf/vscode-front-matter/issues/424): Snippet wrapping to allow easier updates or changes to previously set snippets in the content
- [#585](https://github.com/estruyf/vscode-front-matter/issues/585): New content relationship field type (`contentRelationship`)
- [#598](https://github.com/estruyf/vscode-front-matter/issues/598): Multilingual support
- [#615](https://github.com/estruyf/vscode-front-matter/issues/615): Added support for `astro:assets` - [Astro Assets](https://docs.astro.build/en/guides/assets/)
### 🎨 Enhancements
- [#558](https://github.com/estruyf/vscode-front-matter/issues/558): Moved the tags and categories to a `.frontmatter/database/taxonomyDb.json` file
- [#566](https://github.com/estruyf/vscode-front-matter/issues/566): Keep the panel context on the live preview
- [#568](https://github.com/estruyf/vscode-front-matter/issues/568): Update the preview URL if the slug changes
- [#569](https://github.com/estruyf/vscode-front-matter/issues/569): Remove the page bundle folder on content removal
- [#586](https://github.com/estruyf/vscode-front-matter/issues/586): Allow to specify the content card fields
- [#588](https://github.com/estruyf/vscode-front-matter/issues/588): Added extensibility support to override card fields
- [#591](https://github.com/estruyf/vscode-front-matter/issues/591): Support for date format in the `datetime` field
- [#593](https://github.com/estruyf/vscode-front-matter/issues/593): Add support for date formatting in the preview path
- [#599](https://github.com/estruyf/vscode-front-matter/issues/599): Add a placeholder when the base panel view is empty
- [#602](https://github.com/estruyf/vscode-front-matter/issues/602): Find content outside the Front Matter workspace folder
- [#611](https://github.com/estruyf/vscode-front-matter/issues/611): Fix typo in the `frontMatter.global.disabledNotifications` setting
- [#619](https://github.com/estruyf/vscode-front-matter/issues/619): Added the `fmWebviewUrl` property to be used in the `registerCardImage` extensibility library
### ⚡️ Optimizations
- [#584](https://github.com/estruyf/vscode-front-matter/issues/584): Ignore type field in content-type validation
### 🐞 Fixes
- [#564](https://github.com/estruyf/vscode-front-matter/issues/564): Fix to only pass strings to the taxonomy dashboard
- [#567](https://github.com/estruyf/vscode-front-matter/issues/567): Fix taxonomy filters that are incorrectly positioned
- [#572](https://github.com/estruyf/vscode-front-matter/issues/572): Fix the media snippet placeholder link
- [#577](https://github.com/estruyf/vscode-front-matter/issues/577): Fix in the `dataFile` field where data entries get overwritten
- [#590](https://github.com/estruyf/vscode-front-matter/issues/590): Fix for image fields inside a sub-block
- [#595](https://github.com/estruyf/vscode-front-matter/issues/595): Fix for media metadata now showing up
- [#596](https://github.com/estruyf/vscode-front-matter/issues/596): Fix for number field in block data
- [#603](https://github.com/estruyf/vscode-front-matter/issues/603): Fix problem with page bundles and path placeholders
- [#616](https://github.com/estruyf/vscode-front-matter/issues/616): Fix content filtering
- [#617](https://github.com/estruyf/vscode-front-matter/issues/617): Fix insert media snippet dialog by using a slideover instead of a dialog
- [#620](https://github.com/estruyf/vscode-front-matter/issues/620): Fix in array field of data files
- [#621](https://github.com/estruyf/vscode-front-matter/issues/621): Create data file if it does not exist yet
## [8.4.0] - 2023-04-03 - [Release notes](https://beta.frontmatter.codes/updates/v8.4.0)
### 🧪 Experimental features
- External UI script support for dashboards
- Visual Studio Code Theming support for the dashboards
- Front matter AI 🤖
> **Info**: To enable the experimental features you need to set the `frontMatter.experimental` setting to `true`.
### 🙏 Exclusive Features for Sponsors
We're excited to announce a brand new feature exclusively available to sponsors of Front Matter CMS. With this update, we've added Front Matter AI to the project, which provides helpful suggestions for creating new content such as title suggestions and tag/category suggestions.
> **Important**: To access the Front Matter AI feature, you will need to sign-in ([backers & supports sign-in instructions](https://frontmatter.codes/docs/getting-started#backers-&-supporters)) and set the `frontMatter.sponsors.ai.enabled` setting to `true` and you're good to go! We put it behind a setting to not automatically enable it and let you decide if you want to use it or not.
If you're not already a sponsor, now is a great time to consider supporting the project. By becoming a sponsor, you not only gain access to exclusive features like Front Matter AI, but also help to support the ongoing development and maintenance of the project. You can become a sponsor by visiting the [GitHub sponsor page](https://github.com/sponsors/estruyf).
### ✨ New features
- [#363](https://github.com/estruyf/vscode-front-matter/issues/363): Multiline support for the `string` field in data view
- [#513](https://github.com/estruyf/vscode-front-matter/issues/513): Added support for external UI scripts to add custom HTML on the dashboard elements
- [#530](https://github.com/estruyf/vscode-front-matter/issues/530): Implementation of the Front Matter AI 🤖 powered by [mendable.ai](https://mendable.ai)
- [#537](https://github.com/estruyf/vscode-front-matter/issues/537): Allow to use the root path `/` as the public folder
- [#541](https://github.com/estruyf/vscode-front-matter/issues/541): Added title AI suggestions for GitHub sponsors
- [#548](https://github.com/estruyf/vscode-front-matter/issues/548): Project selection support when working in mono-repos or multi-root workspaces
- [#550](https://github.com/estruyf/vscode-front-matter/issues/550): Added taxonomy (tags/categories) AI suggestions for GitHub sponsors
### 🎨 Enhancements
- Added an `unknown` field for uniforms when it has no type defined
- [#512](https://github.com/estruyf/vscode-front-matter/issues/512): Added the `jsonc` file association for the `frontMatter.json` file. That way, you can use comments in the file.
- [#522](https://github.com/estruyf/vscode-front-matter/issues/522): Configuration support added for [Astro](https://astro.build)
- [#523](https://github.com/estruyf/vscode-front-matter/issues/523): Added support for `floating`/`decimal` numbers with a new number field property called `numberOptions`
- [#524](https://github.com/estruyf/vscode-front-matter/issues/524): Removed the **Global settings** view from the panel. You can still get it back by configuring a [custom view mode](https://frontmatter.codes/docs/panel#view-modes).
- [#535](https://github.com/estruyf/vscode-front-matter/issues/535): Retain the scroll position after selecting a media file
- [#538](https://github.com/estruyf/vscode-front-matter/issues/538): Added support to encode emojis in the string field
- [#549](https://github.com/estruyf/vscode-front-matter/issues/549): Git submodule support to sync changes
- [#554](https://github.com/estruyf/vscode-front-matter/issues/554): When inserting snippets, only the content snippets will be shown
### ⚡️ Optimizations
- [#534](https://github.com/estruyf/vscode-front-matter/issues/534): Moved the `mediaDb.json` file to a `.frontmatter/database` folder instead of the `.frontmatter/content` folder
- [#536](https://github.com/estruyf/vscode-front-matter/issues/536): Set the start location from the script to the root of the workspace
- [#555](https://github.com/estruyf/vscode-front-matter/issues/555): When generating a content-type from existing content, Front Matter will better detect the type of field
- [#556](https://github.com/estruyf/vscode-front-matter/issues/556): Content values are aligned to the type of field
### 🐞 Fixes
- [#518](https://github.com/estruyf/vscode-front-matter/issues/518): Fix an issue where the `YAML` parser adds line breaks to long strings
- [#520](https://github.com/estruyf/vscode-front-matter/issues/520): Add the URL protocol to the host on opening the preview if it's missing
- [#521](https://github.com/estruyf/vscode-front-matter/issues/521): Fix empty snippets dashboard placeholder
- [#526](https://github.com/estruyf/vscode-front-matter/issues/526): Fix card content menu
- [#528](https://github.com/estruyf/vscode-front-matter/issues/528): Fix where the `.astro` code section `---` is seen as front matter
- [#529](https://github.com/estruyf/vscode-front-matter/issues/529): Fix YAML parsing in Windows which added an extra carriage return
- [#531](https://github.com/estruyf/vscode-front-matter/issues/531): Fix prettier update which caused data views to not render list items
- [#539](https://github.com/estruyf/vscode-front-matter/issues/539): Fix the override of the default file prefix on content creation
- [#543](https://github.com/estruyf/vscode-front-matter/issues/543): Fix JSON schema for script commands
- [#547](https://github.com/estruyf/vscode-front-matter/issues/547): Fix setting default value in a hidden group field (`block`)
- [#552](https://github.com/estruyf/vscode-front-matter/issues/552): Fix for content retrieval in multi-root workspaces
- [#557](https://github.com/estruyf/vscode-front-matter/issues/557): Fix for dropdown of the tag picker
## [8.3.0] - 2023-02-14 - [Release notes](https://beta.frontmatter.codes/updates/v8.3.0)
### 🧪 Experimental features
- Visual Studio Code Theming support for the dashboards
> **Info**: To enable the experimental features you need to set the `frontMatter.experimental` setting to `true`.
### ✨ New features
- [#407](https://github.com/estruyf/vscode-front-matter/issues/407): External config support
### 🎨 Enhancements
- [#425](https://github.com/estruyf/vscode-front-matter/issues/425): Added support for placeholders in the content paths and previews
- [#473](https://github.com/estruyf/vscode-front-matter/issues/473): Allow setting the SEO title name with the `frontMatter.taxonomy.seoTitleField` setting
- [#474](https://github.com/estruyf/vscode-front-matter/issues/474): Allow to define the file prefix on content types
- [#484](https://github.com/estruyf/vscode-front-matter/issues/484): Support for overriding scripts per environment type
- [#494](https://github.com/estruyf/vscode-front-matter/issues/494): Support for external image URLs in previews
- [#497](https://github.com/estruyf/vscode-front-matter/issues/497): Support for movie media previews in the content dashboard
- [#502](https://github.com/estruyf/vscode-front-matter/issues/502): Keyboard bindings added to open dashboard, insert media, and insert snippet
- [#503](https://github.com/estruyf/vscode-front-matter/issues/503): Allow making changes to the preview URL in the webview
- [#504](https://github.com/estruyf/vscode-front-matter/issues/504): Allow specifying the filename for your page bundles
- [#505](https://github.com/estruyf/vscode-front-matter/issues/505): Experimental Visual Studio Code theming support
### ⚡️ Optimizations
- [#496](https://github.com/estruyf/vscode-front-matter/issues/496): Make use of the `storageUri` and `globalStorageUri` for storing larger states
### 🐞 Fixes
- [#469](https://github.com/estruyf/vscode-front-matter/issues/469): Fix for using the root folder as content folder
- [#470](https://github.com/estruyf/vscode-front-matter/issues/470): Fix `initialize project` dashboard description
- [#480](https://github.com/estruyf/vscode-front-matter/issues/480): Updated _add missing fields_ label to _add missing fields to content-type_
- [#482](https://github.com/estruyf/vscode-front-matter/issues/482): Update the description when you want to overwrite the default content type description
- [#488](https://github.com/estruyf/vscode-front-matter/issues/488): Fix an issue where the `.frontmatter` folder gets created before initializing the project
- [#493](https://github.com/estruyf/vscode-front-matter/issues/493): Fix an issue where a custom placeholder value is replaced by an `array` instead of a `string`
## [8.2.0] - 2022-12-08 - [Release notes](https://beta.frontmatter.codes/updates/v8.2.0)
### ✨ New features
- [#362](https://github.com/estruyf/vscode-front-matter/issues/362): Support for conditional metadata
- [#412](https://github.com/estruyf/vscode-front-matter/issues/412): Allow `frontmatter.json` to be split in multiple files
### 🎨 Enhancements
- [#360](https://github.com/estruyf/vscode-front-matter/issues/360): Define which content types can be used on your page folders
- [#406](https://github.com/estruyf/vscode-front-matter/issues/406): Added support for single data entries in the data dashboard
- [#428](https://github.com/estruyf/vscode-front-matter/issues/428): Improved UX for inserting images to your content
- [#430](https://github.com/estruyf/vscode-front-matter/issues/430): Support for HEXO its `post_asset_folder` setting (image location)
- [#434](https://github.com/estruyf/vscode-front-matter/issues/434): Webview errors are logged in the extension output
- [#440](https://github.com/estruyf/vscode-front-matter/issues/440): Type to search/filter in the snippets dashboard
- [#447](https://github.com/estruyf/vscode-front-matter/issues/447): Allow to use placeholders on git commit messages
- [#449](https://github.com/estruyf/vscode-front-matter/issues/449): Show `filename` if the `title` is not set
- [#450](https://github.com/estruyf/vscode-front-matter/issues/450): Additional time placeholders added `{{hour12}}`, `{{hour24}}`, `{{ampm}}`, and `{{minute}}`
- [#458](https://github.com/estruyf/vscode-front-matter/issues/458): Ability to configure the file prefix on folder level
### ⚡️ Optimizations
- [#431](https://github.com/estruyf/vscode-front-matter/issues/431): Performance improvements for the content dashboard
- [#448](https://github.com/estruyf/vscode-front-matter/issues/448): Retrieving files fails when content folder name and workspace folder name are the same
- [#455](https://github.com/estruyf/vscode-front-matter/issues/455): Show a description for the SEO section when title nor description is set
### 🐞 Fixes
- Fix field error message color
- [#433](https://github.com/estruyf/vscode-front-matter/issues/433): Fix issue with rendering an incorrect title value on the content dashboard
- [#462](https://github.com/estruyf/vscode-front-matter/issues/462): Fix issue in script error notification
- [#465](https://github.com/estruyf/vscode-front-matter/issues/465): Deleted content does not get added in git when syncing
- [#471](https://github.com/estruyf/vscode-front-matter/issues/471): Fix typo on data dashboard
## [8.1.2] - 2022-10-06
### 🐞 Fixes
- [#435](https://github.com/estruyf/vscode-front-matter/issues/435): Fix required fields text color
- [#436](https://github.com/estruyf/vscode-front-matter/issues/436): Fix inserting image/video snippets without defined fields
## [8.1.1] - 2022-09-23
### 🐞 Fixes
- [#422](https://github.com/estruyf/vscode-front-matter/issues/422): Fix in panel initialization logic
## [8.1.0] - 2022-09-22 - [Release notes](https://beta.frontmatter.codes/updates/v8.1.0)
### ✨ New features
- [#369](https://github.com/estruyf/vscode-front-matter/issues/369): New `required` property to specify if a content-type field is required
- [#376](https://github.com/estruyf/vscode-front-matter/issues/376): Ability to run scripts after content was created
- [#377](https://github.com/estruyf/vscode-front-matter/issues/377): Git sync actions added on panel and content dashboard (pull and push your changes to remote)
- [#379](https://github.com/estruyf/vscode-front-matter/issues/377): New `frontMatter.config.reload` command to reload the configuration file + reinitialize its listeners
- [#391](https://github.com/estruyf/vscode-front-matter/issues/391): New `description` property to show a message underneath the input field
- [#401](https://github.com/estruyf/vscode-front-matter/issues/401): Content dashboard now has pagination enabled and can be disabled via the `frontMatter.dashboard.content.pagination` setting
### 🎨 Enhancements
- [#352](https://github.com/estruyf/vscode-front-matter/issues/352): Custom placeholders now support scripting
- [#370](https://github.com/estruyf/vscode-front-matter/issues/370): Define the tags and categories as reserved keywords for custom taxonomy
- [#372](https://github.com/estruyf/vscode-front-matter/issues/372): Rename Taxonomy tab to Taxonomies
- [#374](https://github.com/estruyf/vscode-front-matter/issues/374): Hide the front matter section to use the panel instead
- [#383](https://github.com/estruyf/vscode-front-matter/issues/383): Add the item menu to the content list view
- [#385](https://github.com/estruyf/vscode-front-matter/issues/385): If no default value for the draft field is defined, the field value will be set to `true`
- [#388](https://github.com/estruyf/vscode-front-matter/issues/388): New stop server action has been added to the panel
- [#390](https://github.com/estruyf/vscode-front-matter/issues/390): Implement another JSON parser in order to be able to parse the `frontmatter.json` file better
- [#394](https://github.com/estruyf/vscode-front-matter/issues/394): Ordering of snippet fields is based on their field definition
- [#395](https://github.com/estruyf/vscode-front-matter/issues/395): Added support for custom snippet fields on media snippets
- [#402](https://github.com/estruyf/vscode-front-matter/issues/402): Custom sorting of content now supports `number` fields
- [#417](https://github.com/estruyf/vscode-front-matter/issues/417): New `hyperlink` wysiwyg option
- [#418](https://github.com/estruyf/vscode-front-matter/issues/418): New `heading` and `divider` fields for your content-type definition
### ⚡️ Optimizations
- Internal post message optimizations to the webviews
- Preview tab now shows the title of the page/content if present
### 🐞 Fixes
- [#378](https://github.com/estruyf/vscode-front-matter/issues/378): Fix last modified update only to content in content folders
- [#384](https://github.com/estruyf/vscode-front-matter/issues/384): Fix issue `title` field in sub-fields
- [#393](https://github.com/estruyf/vscode-front-matter/issues/393): Fix Windows file path for retrieving the preview path
- [#396](https://github.com/estruyf/vscode-front-matter/issues/396): Fix for `index` and `_index` page previews
- [#398](https://github.com/estruyf/vscode-front-matter/issues/398): Fix Windows folder path parsing in data folder retrieval
- [#400](https://github.com/estruyf/vscode-front-matter/issues/400): Fix for draft/published content grouping
- [#403](https://github.com/estruyf/vscode-front-matter/issues/403): Fix for media files with spaces on importing in article content
- [#404](https://github.com/estruyf/vscode-front-matter/issues/404): Fix for published sorting option in media dashboard
- [#408](https://github.com/estruyf/vscode-front-matter/issues/408): Fix for missing `dashboard.taxonomy.view` view mode in the JSON schema
## [8.0.1] - 2022-07-13
### 🐞 Fixes
@@ -8,7 +256,7 @@
- Fix missing clipboard icon for the media card action
- Fix in tags rendering on content cards
## [8.0.0] - 2022-07-11 - [Release notes](https://beta.frontmatter.codes/updates/v8.0.0)
## [8.0.0] - 2022-07-11 - [Release notes](https://beta.frontmatter.codes/updates/v8.0.0)
### ✨ New Features
@@ -52,7 +300,6 @@
- [#346](https://github.com/estruyf/vscode-front-matter/issues/346): Fix media dashboard refresh action
## [7.3.1] - 2022-05-26
### 🐞 Fixes
@@ -79,7 +326,6 @@
- [#334](https://github.com/estruyf/vscode-front-matter/issues/334): Fix for locked content folders retrieval
- [#339](https://github.com/estruyf/vscode-front-matter/issues/339): Fix for content folders without a title
## [7.2.0] - 2022-05-02 - [Release notes](https://beta.frontmatter.codes/updates/v7.2.0)
### 🎨 Enhancements
@@ -121,7 +367,7 @@
## [7.1.0] - 2022-04-07 - [Release notes](https://beta.frontmatter.codes/updates/v7.1.0)
### 🎨 Enhancements
- [#240](https://github.com/estruyf/vscode-front-matter/issues/240): Capability added to define display modes
- [#246](https://github.com/estruyf/vscode-front-matter/issues/246): Support to add multiple tags/keywords/taxonomy via comma separated values
- [#293](https://github.com/estruyf/vscode-front-matter/issues/293): Support added for setting preview images in block fields
@@ -141,7 +387,7 @@
- [#304](https://github.com/estruyf/vscode-front-matter/issues/304): Fix yaml stringify which caused additional fields to be added
- [#305](https://github.com/estruyf/vscode-front-matter/issues/305): Fix for overflow issue in taxonomy picker
- [#306](https://github.com/estruyf/vscode-front-matter/issues/306): Fix for default value of content type fields
- [#311](https://github.com/estruyf/vscode-front-matter/issues/311): Fix for updating snippets
- [#311](https://github.com/estruyf/vscode-front-matter/issues/311): Fix for updating snippets
## [7.0.0] - 2022-03-21 - [Release notes](https://beta.frontmatter.codes/updates/v7.0.0)
@@ -317,7 +563,7 @@ As from this version onwards, the extension will be published to [open-vsx.org](
### 🎨 Enhancements
- [#173](https://github.com/estruyf/vscode-front-matter/issues/173): Allow to specify your own sorting for the content dashboard
- [#174](https://github.com/estruyf/vscode-front-matter/issues/174): Added option to exclude sub-directories from page/markdown content retrieval
- [#174](https://github.com/estruyf/vscode-front-matter/issues/174): Added option to exclude sub-directories from page/markdown content retrieval
## [5.4.0] - 2021-11-05
@@ -463,10 +709,10 @@ As from this version onwards, the extension will be published to [open-vsx.org](
- Fix typo in the `package.json` file for the preview command
## [2.5.0] - 2020-08-19
## [2.5.0] - 2020-08-19
- Moved the center layout button to the other actions section
- [#60](https://github.com/estruyf/vscode-front-matter/issues/60): Added the ability to open a site preview in VS Code
- [#60](https://github.com/estruyf/vscode-front-matter/issues/60): Added the ability to open a site preview in VS Code
## [2.4.1] - 2020-08-16

View File

@@ -25,9 +25,9 @@ Eager to start contributing? Great 🤩, you can contribute to the following pro
- Start by forking this project;
- Clone your fork to your local machine;
- Run `npm i`;
- Run `pnpm i`;
- Open the project in VS Code;
- To start developing, run `npm run dev:ext` and press `f5` to start the debugging session.
- To start developing, run `pnpm dev:ext` and press `f5` to start the debugging session.
### Tips

View File

@@ -10,12 +10,12 @@
<p align="center">
<a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter" title="Check it out on the Visual Studio Marketplace">
<img src="https://vsmarketplacebadge.apphb.com/version/eliostruyf.vscode-front-matter.svg" alt="Visual Studio Marketplace" style="display: inline-block" />
<img src="https://vscode-marketplace-badge.vercel.app/api/badge/version/eliostruyf.vscode-front-matter" alt="Visual Studio Marketplace" style="display: inline-block" />
</a>
<img src="https://vsmarketplacebadge.apphb.com/installs/eliostruyf.vscode-front-matter.svg" alt="Number of installs" style="display: inline-block;margin-left:10px" />
<img src="https://vsmarketplacebadge.apphb.com/rating/eliostruyf.vscode-front-matter.svg" alt="Ratings" style="display: inline-block;margin-left:10px" />
<img src="https://vscode-marketplace-badge.vercel.app/api/badge/installs/eliostruyf.vscode-front-matter" alt="Number of installs" style="display: inline-block;margin-left:10px" />
<img src="https://vscode-marketplace-badge.vercel.app/api/badge/rating/eliostruyf.vscode-front-matter" alt="Ratings" style="display: inline-block;margin-left:10px" />
<a href="https://github.com/sponsors/estruyf" title="Become a sponsor" style="margin-left:10px">
<img src="https://img.shields.io/github/sponsors/estruyf?color=%23CE2E7C&logo=github&style=flat" alt="Sponsor the project" style="display: inline-block" />
@@ -54,6 +54,16 @@ A couple of our extension highlights that hopefully get you interested in giving
> If you see something missing in your article creation flow, please feel free to reach out.
**Version 9**
The extension is now available in multiple languages: English, German, and Japanese. Want to add your language? Check out the [localization the extension](https://frontmatter.codes/docs/contributing#translating-the-extension).
**Version 8**
The taxonomy dashboard got introduced on which you can manage your tags, categories, and custom taxonomy.
![Taxonomy dashboard](https://beta.frontmatter.codes/assets/marketplace/v8.1.0/taxonomy-dashboard.png)
**Version 7**
Snippets support for Front Matter has been added!
@@ -111,7 +121,7 @@ You can get the extension via:
If you have the courage to test out the beta features, we made available a beta version as well. You can install this via:
- Uninstall the main Front Matter version
- Install the beta version
- Install the beta version
- VS Code marketplace: [VS Code Marketplace - Front Matter BETA](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter-beta).
- The extension CLI: `ext install eliostruyf.vscode-front-matter-beta`
- Or by clicking on the following link: <a href="" title="open extension in VS Code" data-vscode="vscode:extension/eliostruyf.vscode-front-matter-beta">open extension in VS Code</a>
@@ -185,6 +195,6 @@ You can open showcase issues for the following things:
<p align="center">
<a href="https://visitorbadge.io">
<img src="https://estruyf-github.azurewebsites.net/api/VisitorHit?user=estruyf&repo=vscode-front-matter&countColor=%23F05450&labelColor=%230E131F" height="25px" />
</a>
</p>
<img src="https://api.visitorbadge.io/api/VisitorHit?user=estruyf&repo=vscode-front-matter&countColor=%23F05450&labelColor=%230E131F" height="25px" />
</a>
</p>

View File

@@ -8,12 +8,12 @@
<p align="center">
<a href="https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter" title="Check it out on the Visual Studio Marketplace">
<img src="https://vsmarketplacebadge.apphb.com/version/eliostruyf.vscode-front-matter.svg" alt="Visual Studio Marketplace" style="display: inline-block" />
<img src="https://vscode-marketplace-badge.vercel.app/api/badge/version/eliostruyf.vscode-front-matter" alt="Visual Studio Marketplace" style="display: inline-block" />
</a>
<img src="https://vsmarketplacebadge.apphb.com/installs/eliostruyf.vscode-front-matter.svg" alt="Number of installs" style="display: inline-block;margin-left:10px" />
<img src="https://vsmarketplacebadge.apphb.com/rating/eliostruyf.vscode-front-matter.svg" alt="Ratings" style="display: inline-block;margin-left:10px" />
<img src="https://vscode-marketplace-badge.vercel.app/api/badge/installs/eliostruyf.vscode-front-matter" alt="Number of installs" style="display: inline-block;margin-left:10px" />
<img src="https://vscode-marketplace-badge.vercel.app/api/badge/rating/eliostruyf.vscode-front-matter" alt="Ratings" style="display: inline-block;margin-left:10px" />
<a href="https://github.com/sponsors/estruyf" title="Become a sponsor" style="margin-left:10px">
<img src="https://img.shields.io/github/sponsors/estruyf?color=%23CE2E7C&logo=github&style=flat" alt="Sponsor the project" style="display: inline-block" />
@@ -52,6 +52,16 @@ A couple of our extension highlights that hopefully get you interested in giving
> If you see something missing in your article creation flow, please feel free to reach out.
**Version 9**
The extension is now available in multiple languages: English, German, and Japanese. Want to add your language? Check out the [localization the extension](https://frontmatter.codes/docs/contributing#translating-the-extension).
**Version 8**
The taxonomy dashboard got introduced on which you can manage your tags, categories, and custom taxonomy.
![Taxonomy dashboard](https://frontmatter.codes/assets/marketplace/v8.1.0/taxonomy-dashboard.png)
**Version 7**
Snippets support for Front Matter has been added!
@@ -109,7 +119,7 @@ You can get the extension via:
If you have the courage to test out the beta features, we made available a beta version as well. You can install this via:
- Uninstall the main Front Matter version
- Install the beta version
- Install the beta version
- VS Code marketplace: [VS Code Marketplace - Front Matter BETA](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter-beta).
- The extension CLI: `ext install eliostruyf.vscode-front-matter-beta`
- Or by clicking on the following link: <a href="" title="open extension in VS Code" data-vscode="vscode:extension/eliostruyf.vscode-front-matter-beta">open extension in VS Code</a>
@@ -157,21 +167,29 @@ You can open showcase issues for the following things:
<p align="center">
<a href="https://github.com/estruyf/vscode-front-matter/graphs/contributors">
<img src="https://contrib.rocks/image?repo=estruyf/vscode-front-matter" />
<img src="https://contrib.rocks/image?repo=estruyf/vscode-front-matter" alt="Front Matter contributors" />
</a>
</p>
## 🖤 Backers & Sponsors 👇 🤘
<p align="center">
<img src="https://frontmatter.codes/api/img-sponsors" />
<img src="https://frontmatter.codes/api/img-sponsors" alt="Front Matter sponsors" />
</p>
<br />
<p align="center" title="Powered by Vercel">
<a href="https://vercel.com/?utm_source=vscode-frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/powered-by-vercel.png" alt="Powered by Vercel" />
</a>
</p>
<br />
<p align="center">
<a href="https://vercel.com/?utm_source=vscode-frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/powered-by-vercel.png" />
<a href="http://bejs.io/" title="Supported by the BEJS Community">
<img src="https://frontmatter.codes/assets/sponsors/bejs-community.png" alt="Supported by the BEJS Community" height="50px"/>
</a>
</p>
@@ -184,6 +202,6 @@ You can open showcase issues for the following things:
<p align="center">
<a href="https://visitorbadge.io">
<img src="https://estruyf-github.azurewebsites.net/api/VisitorHit?user=estruyf&repo=vscode-front-matter&countColor=%23F05450&labelColor=%230E131F" height="25px" />
<img src="https://api.visitorbadge.io/api/VisitorHit?user=estruyf&repo=vscode-front-matter&countColor=%23F05450&labelColor=%230E131F" height="25px" alt="Front Matter visitors" />
</a>
</p>
</p>

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<path fill="#C5C5C5" d="M16 19a6.99 6.99 0 0 1-5.833-3.129l1.666-1.107a5 5 0 0 0 8.334 0l1.666 1.107A6.99 6.99 0 0 1 16 19zm4-11a2 2 0 1 0 2 2a1.98 1.98 0 0 0-2-2zm-8 0a2 2 0 1 0 2 2a1.98 1.98 0 0 0-2-2z"/>
<path fill="#C5C5C5" d="M17.736 30L16 29l4-7h6a1.997 1.997 0 0 0 2-2V6a1.997 1.997 0 0 0-2-2H6a1.997 1.997 0 0 0-2 2v14a1.997 1.997 0 0 0 2 2h9v2H6a4 4 0 0 1-4-4V6a3.999 3.999 0 0 1 4-4h20a3.999 3.999 0 0 1 4 4v14a4 4 0 0 1-4 4h-4.835Z"/>
</svg>

After

Width:  |  Height:  |  Size: 540 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<path fill="#424242" d="M16 19a6.99 6.99 0 0 1-5.833-3.129l1.666-1.107a5 5 0 0 0 8.334 0l1.666 1.107A6.99 6.99 0 0 1 16 19zm4-11a2 2 0 1 0 2 2a1.98 1.98 0 0 0-2-2zm-8 0a2 2 0 1 0 2 2a1.98 1.98 0 0 0-2-2z"/>
<path fill="#424242" d="M17.736 30L16 29l4-7h6a1.997 1.997 0 0 0 2-2V6a1.997 1.997 0 0 0-2-2H6a1.997 1.997 0 0 0-2 2v14a1.997 1.997 0 0 0 2 2h9v2H6a4 4 0 0 1-4-4V6a3.999 3.999 0 0 1 4-4h20a3.999 3.999 0 0 1 4 4v14a4 4 0 0 1-4 4h-4.835Z"/>
</svg>

After

Width:  |  Height:  |  Size: 540 B

View File

@@ -33,20 +33,27 @@
position: inherit !important;
}
.z-10 { z-index: 10 !important; }
.z-20 { z-index: 10 !important; }
.z-10 {
z-index: 10 !important;
}
.z-20 {
z-index: 10 !important;
}
.w-full {
width: 100% !important;
}
.collapsible__body,
.ext_settings {
padding: 1rem 1.25rem;
.ext_settings,
.git_actions,
.initialize_actions {
padding: 1rem 1.25rem;
box-sizing: border-box;
}
#app, .frontmatter {
#app,
.frontmatter {
height: 100%;
}
@@ -56,7 +63,7 @@
align-items: center;
opacity: 0.8;
text-align: center;
padding: 1rem 1.25rem;
padding: 1rem 1.25rem;
}
.spinner,
@@ -101,7 +108,7 @@
padding-bottom: var(--input-margin-vertical);
display: flex;
flex-direction: column;
justify-content: space-between;
justify-content: start;
}
.frontmatter h3 {
@@ -111,7 +118,7 @@
.frontmatter p,
.frontmatter h4,
.frontmatter ul {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
}
.article__tags h3,
@@ -129,7 +136,8 @@
margin-right: 0.5rem;
}
.seo__status__details, .seo__status__keywords {
.seo__status__details,
.seo__status__keywords {
margin-bottom: 1rem;
}
@@ -160,22 +168,11 @@
}
.article__tags__dropbox.open {
border: 1px solid rgba(0, 0, 0, .9);
}
.article__tags__input.freeform {
position: relative;
outline: 1px solid var(--vscode-inputValidation-infoBorder);
outline-offset: -1px;
}
.article__tags__input.freeform input {
padding-right: 35px;
border: 0;
border: 1px solid rgba(0, 0, 0, 0.9);
}
.article__tags ul {
color: var(--vscode-dropdown-foreground);
color: var(--vscode-dropdown-foreground);
background-color: var(--vscode-dropdown-background);
}
@@ -185,16 +182,16 @@
}
.article__tags li:active {
color: var(--vscode-button-foreground);
color: var(--vscode-button-foreground);
background-color: var(--vscode-button-background);
}
.article__tags li[aria-selected="true"] {
.article__tags li[aria-selected='true'] {
color: var(--vscode-button-foreground);
background-color: var(--vscode-button-hoverBackground);
}
.article__tags li[aria-disabled="true"] {
.article__tags li[aria-disabled='true'] {
display: none;
}
@@ -233,7 +230,7 @@
}
.ext_link_block svg {
margin-right: .5rem;
margin-right: 0.5rem;
display: block;
width: 16px;
height: 16px;
@@ -267,16 +264,16 @@
}
.ext_link_block button.active {
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
}
.ext_link_block button.active:hover {
cursor: pointer;
background: var(--vscode-button-hoverBackground);
cursor: pointer;
background: var(--vscode-button-hoverBackground);
}
.ext_link_block a:hover,
.ext_link_block a:active,
.ext_link_block a:hover,
.ext_link_block a:active,
.ext_link_block a:focus,
.ext_link_block a:visited {
color: var(--vscode-button-secondaryForeground);
@@ -310,15 +307,15 @@
}
.table__cell__validation .valid {
color: #46EC86;
color: #46ec86;
}
.table__cell__validation .warning {
color: #E6AF2E;
color: #e6af2e;
}
.table__cell__validation div span + span {
margin-left: .5rem;
margin-left: 0.5rem;
}
.seo__status__note {
@@ -334,7 +331,7 @@
height: 24px;
}
.field__toggle input {
.field__toggle input {
opacity: 0;
width: 0;
height: 0;
@@ -348,21 +345,21 @@
right: 0;
bottom: 0;
background-color: var(--vscode-button-secondaryBackground);
-webkit-transition: .4s;
transition: .4s;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 34px;
}
.field__toggle__slider:before {
position: absolute;
content: "";
content: '';
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 50%;
}
@@ -381,162 +378,6 @@ input:checked + .field__toggle__slider:before {
}
/* Metadata */
.metadata_field {
margin-bottom: 1rem;
}
.vscode-dark .metadata_field__box {
background: rgba(255, 255, 255, 0.1);
border: 1px dashed rgba(255, 255, 255, 0.2);
}
.vscode-light .metadata_field__box {
background: rgba(0, 0, 0, 0.1);
border: 1px dashed rgba(0, 0, 0, 0.2);
}
.metadata_field__box {
background: rgba(255, 255, 255, 0.1);
border: 1px dashed rgba(255, 255, 255, 0.2);
margin-bottom: .5rem;
padding: .5rem 1rem;
}
.metadata_field__label {
display: flex;
align-items: center;
margin-bottom: .5rem;
}
.metadata_field__label.metadata_field__label_parent {
justify-content: center;
}
.metadata_field__label svg {
margin-right: .5rem;
}
.metadata_field__error {
color: var(--vscode-errorForeground);
display: flex;
justify-content: space-between;
align-items: center;
}
.metadata_field__error button {
color: var(--vscode-button-secondaryForeground);
background-color: var(--vscode-button-secondaryBackground);
padding-left: 1rem;
padding-right: 1rem;
width: auto;
}
.metadata_field__error button:hover {
background-color: var(--vscode-button-secondaryHoverBackground);
}
.metadata_field__input, .metadata_field__input:focus,
.metadata_field__textarea, .metadata_field__textarea:focus {
outline: none;
}
.metadata_field__limit {
color: var(--vscode-inputValidation-warningBorder);
margin-top: .25rem;
}
.metadata_field__number {
border: 1px solid var(--vscode-inputValidation-infoBorder) !important;
outline: none !important;
}
.metadata_field__choice__toggle {
color: var(--vscode-input-placeholderForeground);
border: 1px solid var(--vscode-inputValidation-infoBorder) !important;
outline: none !important;
width: 100%;
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
background-color: var(--vscode-input-background);
display: flex;
align-items: center;
position: relative;
}
.metadata_field__choice__toggle:hover,
.metadata_field__choice__toggle:focus,
.metadata_field__choice__toggle:active,
.metadata_field__choice__toggle:disabled {
background-color: var(--vscode-input-background);
}
.metadata_field__choice__toggle span {
margin-right: 1rem;
}
.metadata_field__choice__toggle svg.icon {
height: 1rem;
width: 1rem;
margin-left: .25rem;
position: absolute;
right: .25rem;
}
.metadata_field__choice_list {
width: 90%;
margin: 0;
padding: 0;
z-index: 1;
position: absolute;
list-style: none;
overflow: auto;
max-height: 200px;
color: var(--vscode-dropdown-foreground);
background-color: var(--vscode-dropdown-background);
}
.metadata_field__choice_list.open {
border: 1px solid rgba(0, 0, 0, .9);
}
.metadata_field__choice_list li {
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
cursor: pointer;
}
.metadata_field__choice_list li:active {
color: var(--vscode-button-foreground);
background-color: var(--vscode-button-background);
}
.metadata_field__choice_list li[aria-selected="true"] {
color: var(--vscode-button-foreground);
background-color: var(--vscode-button-hoverBackground);
}
.metadata_field__choice_list li[aria-disabled="true"] {
display: none;
}
.metadata_field__choice_list__item {
opacity: 0.8;
}
.metadata_field__choice__button {
margin-top: .5rem;
display: inline-flex;
align-items: center;
width: auto;
margin-right: .5rem;
}
.metadata_field__choice__button_icon {
height: 1.25rem;
width: 1.25rem;
margin-left: .5rem;
}
.metadata_field__datetime {
display: flex;
@@ -559,75 +400,6 @@ input:checked + .field__toggle__slider:before {
background-color: var(--vscode-button-secondaryHoverBackground);
}
.metadata_field__multiple_images {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
}
.metadata_field__preview_image img {
display: block;
margin: 0 auto;
max-height: 16rem;
}
.metadata_field__file__button,
.metadata_field__preview_image__button {
background-color: transparent;
border: 1px dashed var(--vscode-button-background);
padding: 1.5rem;
filter: brightness(85%);
}
.metadata_field__file__button:hover,
.metadata_field__preview_image__button:hover {
background-color: rgba(255, 255, 255, .1);
filter: brightness(100%);
}
.metadata_field__file__button svg,
.metadata_field__preview_image__button svg {
color: var(--vscode-foreground);
display: block;
width: 3rem;
height: 3rem;
margin: 0 auto;
}
.metadata_field__file__button span,
.metadata_field__preview_image__button span {
color: var(--vscode-foreground);
display: inline-block;
margin: 0 auto;
margin-top: .5rem;
}
.vscode-light .metadata_field__preview_image__preview {
background: rgba(0, 0, 0, 0.1);
}
.vscode-dark .metadata_field__preview_image__preview {
background: rgba(255, 255, 255, 0.1);
}
.metadata_field__preview_image__preview {
background-color: var(--vscode-button-secondaryBackground);
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.metadata_field__preview_image__remove {
background-color: var(--vscode-inputValidation-errorBackground);
color: var(--vscode-inputValidation-errorForeground);
}
.metadata_field__preview_image__remove:hover {
background-color: var(--vscode-inputValidation-errorBackground);
color: var(--vscode-inputValidation-errorForeground);
opacity: .9;
}
/* File list */
.file_list vscode-label {
border-bottom: 1px solid var(--vscode-foreground);
@@ -639,7 +411,7 @@ input:checked + .field__toggle__slider:before {
}
.file_list__items__item {
color: var(--vscode-foreground);
color: var(--vscode-foreground);
font-size: var(--vscode-font-size);
font-weight: var(--vscode-font-weight);
cursor: pointer;
@@ -653,7 +425,7 @@ input:checked + .field__toggle__slider:before {
}
.file_list__items__item:hover {
background-color: var(--vscode-list-hoverBackground);
background-color: var(--vscode-list-hoverBackground);
color: var(--vscode-list-hoverForeground);
cursor: pointer;
}
@@ -663,7 +435,7 @@ input:checked + .field__toggle__slider:before {
flex-shrink: 0;
height: 20px;
width: 20px;
margin-right: .25rem;
margin-right: 0.25rem;
}
.file_list__items__item span {
@@ -688,7 +460,7 @@ input:checked + .field__toggle__slider:before {
.sponsor svg {
height: 20px;
width: 20px;
margin-right: .25rem;
margin-right: 0.25rem;
}
.sponsor a {
@@ -705,7 +477,7 @@ input:checked + .field__toggle__slider:before {
}
.sponsor a > span {
margin-right: .25rem;
margin-right: 0.25rem;
}
/* Timepicker */
@@ -728,4 +500,4 @@ input:checked + .field__toggle__slider:before {
.react-datepicker-time__input input {
border: 1px solid #aeaeae !important;
}
}

View File

@@ -42,8 +42,8 @@ describe("Initialization testing", function() {
await sleep(1000);
await VSBrowser.instance.driver.wait(() => {
return notificationExists(workbench, 'Front Matter:');
await VSBrowser.instance.driver.wait(() => {
return notificationExists(workbench, 'Front Matter:');
}, 2000) as Notification;
const notifications = await workbench.getNotifications();
@@ -68,13 +68,11 @@ describe("Initialization testing", function() {
async function notificationExists(workbench: Workbench, text: string): Promise<Notification | undefined> {
const notifications = await (await (new StatusBar()).openNotificationsCenter()).getNotifications(NotificationType.Info);
console.log(`Notifications:`, notifications.length);
for (const notification of notifications) {
const message = await notification.getMessage();
console.log(message)
if (message.indexOf(text) >= 0) {
return notification;
}
}
}
}

View File

@@ -1,33 +1,33 @@
import * as path from 'path';
import * as semver from "semver";
import { ExTester, ReleaseQuality } from "vscode-extension-tester";
import * as path from 'path'
import * as semver from 'semver'
import { ExTester, ReleaseQuality } from 'vscode-extension-tester'
async function main(): Promise<void> {
const vsCodeVersion: semver.SemVer = new semver.SemVer(`1.66.0`);
const version = vsCodeVersion.version;
const vsCodeVersion: semver.SemVer = new semver.SemVer(`1.66.0`)
const version = vsCodeVersion.version
const storageFolder = path.join(__dirname, "..", "storage");
const extFolder = path.join(__dirname, "..", "extensions");
const storageFolder = path.join(__dirname, '..', 'storage')
const extFolder = path.join(__dirname, '..', 'extensions')
try {
const testPath = path.join(__dirname, "command.test.js");
const testPath = path.join(__dirname, 'command.test.js')
const exTester = new ExTester(storageFolder, ReleaseQuality.Stable, extFolder);
await exTester.downloadCode(version);
await exTester.installVsix();
const exTester = new ExTester(storageFolder, ReleaseQuality.Stable, extFolder)
await exTester.downloadCode(version)
await exTester.installVsix({ useYarn: false })
// await exTester.installFromMarketplace("eliostruyf.vscode-front-matter");
await exTester.downloadChromeDriver(version);
await exTester.downloadChromeDriver(version)
// await exTester.setupRequirements({vscodeVersion: version});
const result = await exTester.runTests(testPath, {
vscodeVersion: version
});
vscodeVersion: version,
resources: [storageFolder],
})
process.exit(result);
process.exit(result)
} catch (err) {
console.log(err);
process.exit(1);
console.log(err)
process.exit(1)
}
}
main();
main()

BIN
enhancements.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
fixes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

View File

@@ -33,7 +33,7 @@
"type": "string",
"name": "year",
"title": "Year",
"default": "2022"
"default": "{{year}}"
},
{
"type": "string",

336
l10n/bundle.l10n.de.json Normal file
View File

@@ -0,0 +1,336 @@
{
"common.add": "Hinzufügen",
"common.edit": "Bearbeiten",
"common.delete": "Löschen",
"common.cancel": "Abbrechen",
"common.clear": "Löschen",
"common.clear.value": "Wert löschen",
"common.search": "Suchen",
"common.save": "Speichern",
"common.menu": "Menü",
"common.insert": "Einfügen",
"common.insert.snippet": "Snippet einfügen",
"common.title": "Titel",
"common.description": "Beschreibung",
"common.retry": "Erneut versuchen",
"common.update": "Aktualisieren",
"common.information": "Info",
"common.important": "Wichtig",
"common.sync": "Synchronisieren",
"common.slug": "Slug",
"common.support": "Support",
"common.remove.value": "{0} entfernen",
"common.error.message": "Entschuldigung, etwas ist schiefgelaufen.",
"developer.title": "Entwicklermodus",
"developer.reload.title": "Dashboard neu laden",
"developer.reload.label": "Neu laden",
"developer.devTools.title": "Entwicklertools öffnen",
"developer.devTools.label": "DevTools",
"field.required": "Pflichtfeld",
"field.unknown": "Unbekanntes Feld",
"dashboard.chatbot.answer.answer": "Antwort",
"dashboard.chatbot.answer.resources": "Ressourcen",
"dashboard.chatbot.answer.warning": "Warnung: Antworten können falsch sein. Im Zweifelsfall konsultieren Sie bitte die Dokumentation.",
"dashboard.chatbot.chatbot.loading": "Assistent wird vorbereitet",
"dashboard.chatbot.chatbot.ready": "Ich bin bereit, was möchtest du wissen?",
"dashboard.chatbot.chatbox.placeholder": "Wie kann ich Front Matter konfigurieren?",
"dashboard.chatbot.header.heading": "Frag den Front Matter AI",
"dashboard.chatbot.header.description": "Unser KI-System, powered by mendable.ai, hat die Dokumentation verarbeitet und kann Ihnen bei Fragen zu Front Matter behilflich sein. Legen Sie los und fragen Sie!",
"dashboard.common.choiceButton.open": "Optionen öffnen",
"dashboard.contents.contentActions.actionMenuButton.title": "Menü",
"dashboard.contents.contentActions.menuItem.view": "Anzeigen",
"dashboard.contents.contentActions.alert.title": "Löschen: {0}",
"dashboard.contents.contentActions.alert.description": "Möchten Sie den Inhalt \"{0}\" wirklich löschen?",
"dashboard.contents.item.invalidTitle": "<ungültiger Titel>",
"dashboard.contents.item.invalidDescription": "<ungültige Beschreibung>",
"dashboard.contents.list.title": "Titel",
"dashboard.contents.list.date": "Datum",
"dashboard.contents.list.status": "Status",
"dashboard.contents.overview.noMarkdown": "Kein Markdown vorhanden",
"dashboard.contents.overview.noFolders": "Stellen Sie sicher, dass Sie einen Inhaltsordner in Ihrem Projekt registriert haben, damit Front Matter die Inhalte finden kann.",
"dashboard.contents.status.draft": "Entwurf",
"dashboard.contents.status.published": "Veröffentlicht",
"dashboard.dataView.dataForm.modify": "Daten bearbeiten",
"dashboard.dataView.dataForm.add": "Neue Daten hinzufügen",
"dashboard.dataView.dataView.select": "Wählen Sie Ihren Datentyp",
"dashboard.dataView.dataView.title": "Ihre {0} Dateneinträge",
"dashboard.dataView.dataView.add": "Neuen Eintrag hinzufügen",
"dashboard.dataView.dataView.empty": "Keine {0} Dateneinträge gefunden",
"dashboard.dataView.dataView.createOrModify": "Erstellen oder bearbeiten Sie Ihre {0} Daten",
"dashboard.dataView.dataView.getStarted": "Wählen Sie einen Datentyp, um zu beginnen",
"dashboard.dataView.dataView.noDataFiles": "Keine Datendateien gefunden",
"dashboard.dataView.dataView.getStarted.link": "Lesen Sie mehr, um zu erfahren, wie Sie Datenfiles verwenden können",
"dashboard.dataView.emptyView.heading": "Wählen Sie zuerst Ihren Datentyp aus",
"dashboard.dataView.sortableItem.editButton.title": "\"{0}\" bearbeiten",
"dashboard.dataView.sortableItem.deleteButton.title": "\"{0}\" löschen",
"dashboard.dataView.sortableItem.alert.title": "Daten-Eintrag löschen",
"dashboard.dataView.sortableItem.alert.description": "Sind Sie sicher, dass Sie den Daten-Eintrag löschen möchten?",
"dashboard.errorView.description": "Bitte schließen Sie das Dashboard und versuchen Sie es erneut.",
"dashboard.header.breadcrumb.home": "Startseite",
"dashboard.header.clearFilters.title": "Filter, Gruppierung und Sortierung zurücksetzen",
"dashboard.header.filter.default": "Kein Filter",
"dashboard.header.folders.default": "Alle Typen",
"dashboard.header.folders.menuButton.showing": "Anzeige",
"dashboard.header.grouping.option.none": "Keine",
"dashboard.header.grouping.option.year": "Jahr",
"dashboard.header.grouping.option.draft": "Entwurf/Veröffentlicht",
"dashboard.header.grouping.menuButton.label": "Gruppieren nach",
"dashboard.header.navigation.allArticles": "Alle Artikel",
"dashboard.header.navigation.published": "Veröffentlicht",
"dashboard.header.navigation.draft": "Im Entwurf",
"dashboard.header.header.createContent": "Inhalt erstellen",
"dashboard.header.header.createByContentType": "Nach Inhaltstyp erstellen",
"dashboard.header.header.createByTemplate": "Nach Vorlage erstellen",
"dashboard.header.pagination.first": "Erste",
"dashboard.header.pagination.previous": "Vorherige",
"dashboard.header.pagination.next": "Nächste",
"dashboard.header.pagination.last": "Letzte",
"dashboard.header.paginationStatus.text": "Zeige {0} bis {1} von {2} Ergebnissen",
"dashboard.header.projectSwitcher.label": "Projekt",
"dashboard.header.refreshDashboard.label": "Dashboard aktualisieren",
"dashboard.header.sorting.lastModified.asc": "Zuletzt geändert (aufsteigend)",
"dashboard.header.sorting.lastModified.desc": "Zuletzt geändert (absteigend)",
"dashboard.header.sorting.filename.asc": "Nach Dateiname (aufsteigend)",
"dashboard.header.sorting.filename.desc": "Nach Dateiname (absteigend)",
"dashboard.header.sorting.published.asc": "Veröffentlicht (aufsteigend)",
"dashboard.header.sorting.published.desc": "Veröffentlicht (absteigend)",
"dashboard.header.sorting.size.asc": "Größe (aufsteigend)",
"dashboard.header.sorting.size.desc": "Größe (absteigend)",
"dashboard.header.sorting.caption.asc": "Beschriftung (aufsteigend)",
"dashboard.header.sorting.caption.desc": "Beschriftung (absteigend)",
"dashboard.header.sorting.alt.asc": "Alt-Text (aufsteigend)",
"dashboard.header.sorting.alt.desc": "Alt-Text (absteigend)",
"dashboard.header.sorting.label": "Sortieren nach",
"dashboard.header.startup.label": "Beim Start öffnen?",
"dashboard.header.tabs.contents": "Inhalte",
"dashboard.header.tabs.media": "Medien",
"dashboard.header.tabs.snippets": "Snippets",
"dashboard.header.tabs.data": "Daten",
"dashboard.header.tabs.taxonomies": "Taxonomien",
"dashboard.header.viewSwitch.toGrid": "Zur Rasteransicht wechseln",
"dashboard.header.viewSwitch.toList": "Zur Listenansicht wechseln",
"dashboard.layout.sponsor.support.msg": "Unterstützen Sie Front Matter",
"dashboard.layout.sponsor.review.label": "Bewerten",
"dashboard.layout.sponsor.review.msg": "Bewerten Sie Front Matter",
"dashboard.media.common.title": "Titel",
"dashboard.media.common.caption": "Beschriftung",
"dashboard.media.common.alt": "Alternativer Text",
"dashboard.media.common.size": "Größe",
"dashboard.media.dialog.title": "Details anzeigen",
"dashboard.media.panel.close": "Panel schließen",
"dashboard.media.metadata.panel.title": "Metadaten aktualisieren",
"dashboard.media.metadata.panel.description": "Geben Sie die Metadaten für die Datei ein.",
"dashboard.media.metadata.panel.field.fileName": "Dateiname",
"dashboard.media.metadata.panel.form.metadata.title": "Metadaten",
"dashboard.media.metadata.panel.form.information.title": "Informationen",
"dashboard.media.metadata.panel.form.information.createdDate": "Erstellt am",
"dashboard.media.metadata.panel.form.information.modifiedDate": "Zuletzt geändert",
"dashboard.media.metadata.panel.form.information.dimensions": "Abmessungen",
"dashboard.media.metadata.panel.form.information.folder": "Ordner",
"dashboard.media.folderCreation.hexo.create": "Post-Asset-Ordner erstellen",
"dashboard.media.folderCreation.folder.create": "Neuen Ordner erstellen",
"dashboard.media.item.quickAction.insert.field": "Bild in Ihrem Feld \"{0}\" einfügen",
"dashboard.media.item.quickAction.insert.markdown": "Bild mit Markdown-Markup einfügen",
"dashboard.media.item.quickAction.copy.path": "Medienpfad kopieren",
"dashboard.media.item.quickAction.delete": "Medien-Datei löschen",
"dashboard.media.item.menuItem.edit.metadata": "Metadaten bearbeiten",
"dashboard.media.item.menuItem.insert.image": "Bild einfügen",
"dashboard.media.item.menuItem.reveal.media": "Medien anzeigen",
"dashboard.media.item.infoDialog.snippet.description": "Wählen Sie das Media-Snippet aus, das für die aktuelle Mediendatei verwendet werden soll.",
"dashboard.media.item.alert.delete.description": "Sind Sie sicher, dass Sie die Datei aus dem Ordner {0} löschen möchten?",
"dashboard.media.media.description": "Wählen Sie die Medien-Datei aus, die Sie Ihrem Inhalt hinzufügen möchten.",
"dashboard.media.media.dragAndDrop": "Sie können Bilder auch per Drag & Drop von Ihrem Desktop auswählen, nachdem sie hochgeladen wurden.",
"dashboard.media.media.folder.upload": "Zu {0} hochladen",
"dashboard.media.media.folder.default": "Kein Ordner ausgewählt, die Dateien, die Sie ablegen, werden dem Ordner {0} hinzugefügt",
"dashboard.media.media.placeholder": "Keine Medien-Dateien vorhanden. Sie können neue Dateien per Drag & Drop unter Verwendung der [Shift]-Taste hinzufügen.",
"dashboard.media.media.contentFolder": "Inhaltsordner",
"dashboard.media.media.publicFolder": "Öffentlicher Ordner",
"dashboard.media.mediaHeaderTop.searchbox.placeholder": "In Ordner suchen",
"dashboard.media.mediaSnippetForm.formDialog.title": "Medien einfügen: {0}",
"dashboard.media.mediaSnippetForm.formDialog.description": "Fügen Sie die {0}-Mediendatei in den aktuellen Artikel ein",
"dashboard.preview.input.placeholder": "Geben Sie eine URL ein",
"dashboard.preview.button.navigate.title": "Navigieren",
"dashboard.preview.button.refresh.title": "Aktualisieren",
"dashboard.preview.button.open.title": "Öffnen",
"dashboard.snippetsView.item.quickAction.editSnippet": "Snippet bearbeiten",
"dashboard.snippetsView.item.quickAction.deleteSnippet": "Snippet löschen",
"dashboard.snippetsView.item.quickAction.viewSnippet": "Snippet-Datei anzeigen",
"dashboard.snippetsView.item.insert.formDialog.title": "Snippet einfügen: {0}",
"dashboard.snippetsView.item.insert.formDialog.description": "Fügen Sie das {0}-Snippet in den aktuellen Artikel ein",
"dashboard.snippetsView.item.edit.formDialog.title": "Snippet bearbeiten: {0}",
"dashboard.snippetsView.item.edit.formDialog.description": "Bearbeiten Sie das {0}-Snippet",
"dashboard.snippetsView.item.alert.title": "Snippet löschen: {0}",
"dashboard.snippetsView.item.alert.description": "Sind Sie sicher, dass Sie das {0}-Snippet löschen möchten?",
"dashboard.snippetsView.newForm.snippetInput.title.placeholder": "Titel des Schnipsels",
"dashboard.snippetsView.newForm.snippetInput.description.label": "Beschreibung",
"dashboard.snippetsView.newForm.snippetInput.description.placeholder": "Beschreibung des Schnipsels",
"dashboard.snippetsView.newForm.snippetInput.snippet.label": "Schnipsel",
"dashboard.snippetsView.newForm.snippetInput.snippet.placeholder": "Inhalt des Schnipsels",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.label": "Ist ein Medienschnipsel?",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.checkbox.label": "Medienschnipsel",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.checkbox.description": "Verwende diesen Schnipsel, um Medieninhalte in deine Seiten einzufügen.",
"dashboard.snippetsView.newForm.snippetInput.docsButton.title": "Erfahre mehr über die Verwendung von Platzhaltern für Medienschnipsel",
"dashboard.snippetsView.newForm.snippetInput.docsButton.description": "In unserer Dokumentation zu Medienschnipsel-Platzhaltern erfährst du, welche Platzhalter du verwenden kannst.",
"dashboard.snippetsView.snippets.ariaLabel": "Überschrift der Schnipsel",
"dashboard.snippetsView.snippets.button.create": "Neuen Schnipsel erstellen",
"dashboard.snippetsView.snippets.select.description": "Wähle den Schnipsel aus, den du deinem Inhalt hinzufügen möchtest.",
"dashboard.snippetsView.snippets.empty.message": "Keine Schnipsel gefunden",
"dashboard.snippetsView.snippets.readMore": "Erfahre mehr über die Verwendung von Schnipseln",
"dashboard.snippetsView.snippets.formDialog.title": "Einen Schnipsel erstellen",
"dashboard.steps.stepsToGetStarted.button.addFolder.title": "Als Inhaltsordner zu Front Matter hinzufügen",
"dashboard.steps.stepsToGetStarted.initializeProject.name": "Projekt initialisieren",
"dashboard.steps.stepsToGetStarted.initializeProject.description": "Mit der Projektinitialisierung werden die erforderlichen Dateien und Ordner für die Verwendung des Front Matter CMS erstellt. Starte mit einem Klick auf diese Aktion.",
"dashboard.steps.stepsToGetStarted.framework.name": "Vorlagen für Frameworks",
"dashboard.steps.stepsToGetStarted.framework.description": "Wähle deinen Site-Generator oder dein Framework aus, um einige der empfohlenen Einstellungen vorzubelegen.",
"dashboard.steps.stepsToGetStarted.framework.select": "Wähle dein Framework aus",
"dashboard.steps.stepsToGetStarted.framework.select.other": "andere",
"dashboard.steps.stepsToGetStarted.contentFolders.name": "Inhaltsordner registrieren",
"dashboard.steps.stepsToGetStarted.contentFolders.description": "Füge einen der in deinem Projekt gefundenen Ordner als Inhaltsordner hinzu. Sobald ein Ordner festgelegt ist, kann Front Matter alle Inhalte auflisten und das Erstellen von Inhalten ermöglichen.",
"dashboard.steps.stepsToGetStarted.contentFolders.label": "Ordner mit Inhalten:",
"dashboard.steps.stepsToGetStarted.contentFolders.information.description": "Du kannst diese Aktion auch aus der Explorer-Ansicht durchführen, indem du mit der rechten Maustaste auf den Ordner klickst und 'Ordner registrieren' auswählst.",
"dashboard.steps.stepsToGetStarted.tags.name": "Alle Tags und Kategorien importieren (optional)",
"dashboard.steps.stepsToGetStarted.tags.description": "Jetzt, da Front Matter alle Inhaltsordner kennt, möchtest du alle Tags und Kategorien aus den verfügbaren Inhalten importieren?",
"dashboard.steps.stepsToGetStarted.showDashboard.name": "Dashboard anzeigen",
"dashboard.steps.stepsToGetStarted.showDashboard.description": "Sobald alle Aktionen abgeschlossen sind, kann das Dashboard geladen werden.",
"dashboard.taxonomyView.button.add.title": "{0} zur Taxonomie hinzufügen",
"dashboard.taxonomyView.button.edit.title": "{0} bearbeiten",
"dashboard.taxonomyView.button.merge.title": "{0} zusammenführen",
"dashboard.taxonomyView.button.move.title": "In eine andere Taxonomie verschieben",
"dashboard.taxonomyView.button.delete.title": "{0} löschen",
"dashboard.taxonomyView.taxonomyLookup.button.title": "Inhalte mit {0} in {1} anzeigen",
"dashboard.taxonomyView.taxonomyManager.description": "{0} deiner Website erstellen, bearbeiten und verwalten",
"dashboard.taxonomyView.taxonomyManager.button.create": "Neuen {0}-Wert erstellen",
"dashboard.taxonomyView.taxonomyManager.table.heading.name": "Name",
"dashboard.taxonomyView.taxonomyManager.table.heading.count": "Anzahl",
"dashboard.taxonomyView.taxonomyManager.table.heading.action": "Aktion",
"dashboard.taxonomyView.taxonomyManager.table.row.empty": "Keine {0} gefunden",
"dashboard.taxonomyView.taxonomyManager.table.unmapped.title": "In den Einstellungen nicht gefunden",
"dashboard.taxonomyView.taxonomyView.navigationBar.title": "Taxonomie auswählen",
"dashboard.taxonomyView.taxonomyView.button.import": "Taxonomie importieren",
"dashboard.taxonomyView.taxonomyView.navigationItem.tags": "Tags",
"dashboard.taxonomyView.taxonomyView.navigationItem.categories": "Kategorien",
"dashboard.unkownView.title": "Ansicht existiert nicht",
"dashboard.unkownView.description": "Du hast anscheinend eine Ansicht geöffnet, die nicht existiert. Bitte öffne das Dashboard erneut.",
"dashboard.welcomeScreen.title": "Verwalte deine statische Website mit Front Matter",
"dashboard.welcomeScreen.thanks": "Vielen Dank, dass du Front Matter verwendest!",
"dashboard.welcomeScreen.description": "Wir bemühen uns, Front Matter so benutzerfreundlich wie möglich zu gestalten, aber wenn du Fragen oder Vorschläge hast, zögere bitte nicht, uns auf GitHub zu kontaktieren.",
"dashboard.welcomeScreen.link.github.title": "GitHub",
"dashboard.welcomeScreen.link.github.label": "GitHub / Dokumentation",
"dashboard.welcomeScreen.link.sponsor.title": "Werde Sponsor",
"dashboard.welcomeScreen.link.sponsor.label": "Sponsor",
"dashboard.welcomeScreen.link.review.title": "Eine Bewertung schreiben",
"dashboard.welcomeScreen.link.review.label": "Bewertung schreiben",
"dashboard.welcomeScreen.actions.heading": "Führe die nächsten Schritte aus, um mit der Erweiterung zu beginnen",
"dashboard.welcomeScreen.actions.description": "Du kannst die Erweiterung auch über das Front Matter-Seitenpanel verwenden. Dort findest du die Aktionen, die speziell für deine Seiten ausgeführt werden können.",
"dashboard.welcomeScreen.actions.thanks": "Wir hoffen, dass du Freude an Front Matter hast!",
"panel.contentType.contentTypeValidator.title": "Inhaltstyp",
"panel.contentType.contentTypeValidator.hint": "Wir haben Unterschiede zwischen dem Inhaltstyp und den Front-Matter-Daten festgestellt. Möchtest du den Inhaltstyp für diesen Inhalt erstellen, aktualisieren oder festlegen?",
"panel.contentType.contentTypeValidator.button.create": "Inhaltstyp erstellen",
"panel.contentType.contentTypeValidator.button.add": "Fehlende Felder zum Inhaltstyp hinzufügen",
"panel.contentType.contentTypeValidator.button.change": "Inhaltstyp der Datei ändern",
"panel.dataBlock.dataBlockField.group.selected.edit": "Bearbeiten: {0}",
"panel.dataBlock.dataBlockField.group.selected.create": "Neuen {0} erstellen",
"panel.dataBlock.dataBlockField.group.select": "Gruppe auswählen",
"panel.dataBlock.dataBlockField.add": "{0} hinzufügen",
"panel.dataBlock.dataBlockRecord.edit": "Datensatz bearbeiten",
"panel.dataBlock.dataBlockRecord.delete": "Datensatz löschen",
"panel.dataBlock.dataBlockRecords.label": "Datensätze",
"panel.dataBlock.dataBlockSelector.label": "Blocktyp",
"panel.errorBoundary.fieldBoundary.label": "Fehler beim Anzeigen des Felds",
"panel.fields.choiceField.select": "{0} auswählen",
"panel.fields.choiceField.clear": "Wert löschen",
"panel.fields.contentTypeRelationshipField.loading": "Lade mögliche Werte...",
"panel.fields.dateTimeField.button.pick": "Wähle dein Datum",
"panel.fields.dateTimeField.time": "Uhrzeit",
"panel.fields.fieldMessage.required": "Das Feld {0} ist erforderlich",
"panel.fields.fileField.delete": "Datei löschen",
"panel.fields.fileField.add": "Ihre {0} hinzufügen",
"panel.fields.imageFallback.label": "Das Bild konnte nicht geladen werden",
"panel.fields.listField.edit": "Eintrag bearbeiten",
"panel.fields.listField.delete": "Eintrag löschen",
"panel.fields.previewImage.remove": "Bild entfernen",
"panel.fields.previewImageField.add": "Ihre {0} hinzufügen",
"panel.fields.slugField.update": "Aktualisierung verfügbar",
"panel.fields.slugField.generate": "Slug generieren",
"panel.fields.textField.ai.message": "Verwenden Sie Front Matter AI, um {0} vorzuschlagen",
"panel.fields.textField.ai.generate": "Vorschlag wird generiert...",
"panel.fields.textField.loading": "Feld wird geladen",
"panel.fields.textField.limit": "Feldgrenze erreicht {0}",
"panel.fields.wrapperField.unknown": "Unbekannter Feldtyp: {0}",
"panel.actions.title": "Aktionen",
"panel.articleDetails.title": "Weitere Details",
"panel.articleDetails.type": "Typ",
"panel.articleDetails.total": "Gesamt",
"panel.articleDetails.headings": "Überschriften",
"panel.articleDetails.paragraphs": "Absätze",
"panel.articleDetails.internalLinks": "Interne Links",
"panel.articleDetails.externalLinks": "Externe Links",
"panel.articleDetails.images": "Bilder",
"panel.baseView.initialize": "Projekt initialisieren",
"panel.baseView.actions.title": "Aktionen",
"panel.baseView.action.openDashboard": "Dashboard öffnen",
"panel.baseView.action.openPreview": "Vorschau öffnen",
"panel.baseView.action.createContent": "Inhalt erstellen",
"panel.baseView.empty": "Öffnen Sie eine Datei, um weitere Aktionen anzuzeigen",
"panel.fileList.label.singular": "Datei",
"panel.fileList.label.plural": "Dateien",
"panel.folderAndFiles.title": "Zuletzt geändert",
"panel.globalSettings.title": " Globale Einstellungen",
"panel.globalSettings.action.modifiedDate.label": "Änderungsdatum",
"panel.globalSettings.action.modifiedDate.description": "Änderungsdatum automatisch aktualisieren",
"panel.globalSettings.action.frontMatter.label": "Front Matter hervorheben",
"panel.globalSettings.action.frontMatter.description": "Front Matter hervorheben",
"panel.globalSettings.action.preview.label": "Lokale Vorschau",
"panel.globalSettings.action.preview.placeholder": "Beispiel: {0}",
"panel.globalSettings.action.server.label": "Lokaler Serverbefehl",
"panel.globalSettings.action.server.placeholder": "Beispiel: {0}",
"panel.metadata.title": "Metadaten",
"panel.otherActions.title": "Weitere Aktionen",
"panel.otherActions.writingSettings.enabled": "Schreib-Einstellungen aktiviert",
"panel.otherActions.writingSettings.disabled": "Schreib-Einstellungen aktivieren",
"panel.otherActions.centerMode": "Zentriermodus umschalten",
"panel.otherActions.createTemplate": "Vorlage erstellen",
"panel.otherActions.revealFile": "Datei im Ordner anzeigen",
"panel.otherActions.openProject": "Projektordner anzeigen",
"panel.otherActions.documentation": "Dokumentation öffnen",
"panel.otherActions.settings": "Einstellungen anzeigen",
"panel.otherActions.issue": "Problem melden",
"panel.preview.title": "Vorschau öffnen",
"panel.publishAction.publish": "Veröffentlichen",
"panel.publishAction.unpublish": "Zurück zu Entwurf",
"panel.seoDetails.recommended": "Empfohlen",
"panel.seoKeywordInfo.density": "Stichwortdichte {0} *",
"panel.seoKeywordInfo.validInfo.label": "Verwendet in Überschrift(en)",
"panel.seoKeywordInfo.validInfo.content": "Inhalt",
"panel.seoKeywords.title": "Stichwörter",
"panel.seoKeywords.header.keyword": "Stichwort",
"panel.seoKeywords.header.details": "Details",
"panel.seoKeywords.density": "* Eine Stichwortdichte von 1-1,5 % ist in den meisten Fällen ausreichend.",
"panel.seoStatus.title": "Empfehlungen",
"panel.seoStatus.header.property": "Eigenschaft",
"panel.seoStatus.header.length": "Länge",
"panel.seoStatus.header.valid": "Gültig",
"panel.seoStatus.seoFieldInfo.characters": "{0} Zeichen",
"panel.seoStatus.seoFieldInfo.words": "{0} Wörter",
"panel.seoStatus.seoFieldInfo.article": "Artikellänge",
"panel.seoStatus.collapsible.title": "SEO-Status",
"panel.seoStatus.required": "{0} oder {1} ist erforderlich.",
"panel.slugAction.title": "Slug optimieren",
"panel.spinner.loading": "Laden...",
"panel.startServerbutton.start": "Server starten",
"panel.startServerbutton.stop": "Server stoppen",
"panel.tag.add": "{0} zu Ihren Einstellungen hinzufügen",
"panel.tagPicker.inputPlaceholder.empty": "{0} auswählen",
"panel.tagPicker.inputPlaceholder.disabled": "Sie haben das Limit von {0} erreicht",
"panel.tagPicker.ai.suggest": "Front Matter AI verwenden, um {0} vorzuschlagen",
"panel.tagPicker.ai.generating": "Vorschläge werden generiert...",
"panel.tagPicker.limit": "Max.: {0}",
"panel.tagPicker.unkown": "Unbekanntes Tag hinzufügen",
"panel.tags.tag.warning": "Achtung, dieses Tag \"{0}\" wird nicht in Ihren Einstellungen gespeichert. Sobald es entfernt ist, wird es unwiederbringlich verloren sein.",
"panel.viewPanel.mediaInsert": "Fahren Sie mit dem Medien-Dashboard fort, um das Bild auszuwählen, das Sie einfügen möchten.",
"dashboard.steps.stepsToGetStarted.assetsFolder.name": "Wo befindet sich Ihr Assets-Ordner?",
"dashboard.steps.stepsToGetStarted.assetsFolder.description": "Wählen Sie den Ordner aus, der Ihre Assets enthält. In diesem Ordner werden alle Ihre Mediendateien für Ihre Artikel gespeichert.",
"dashboard.steps.stepsToGetStarted.assetsFolder.public.title": "Verwende den 'public'-Ordner",
"dashboard.steps.stepsToGetStarted.assetsFolder.assets.title": "Verwende den Astro-Assets-Ordner (src/assets)",
"dashboard.steps.stepsToGetStarted.assetsFolder.other.description": "Wenn Sie einen anderen Ordner konfigurieren möchten, können Sie dies manuell in der frontmatter.json-Datei tun."
}

336
l10n/bundle.l10n.ja.json Normal file
View File

@@ -0,0 +1,336 @@
{
"common.add": "追加",
"common.edit": "編集",
"common.delete": "削除",
"common.cancel": "キャンセル",
"common.clear": "クリア",
"common.clear.value": "値をクリア",
"common.search": "検索",
"common.save": "保存",
"common.menu": "メニュー",
"common.insert": "挿入",
"common.insert.snippet": "スニペットを挿入",
"common.title": "タイトル",
"common.description": "概要",
"common.retry": "再読み込み",
"common.update": "更新",
"common.information": "確認",
"common.important": "重要",
"common.sync": "同期",
"common.slug": "スラッグ",
"common.support": "サポート",
"common.remove.value": "{0}を削除",
"common.error.message": "申し訳ありません。エラーが発生しました。",
"developer.title": "開発モード",
"developer.reload.title": "ダッシュボードを再読み込み",
"developer.reload.label": "再読み込み",
"developer.devTools.title": "開発ツールを開く",
"developer.devTools.label": "開発ツール",
"field.required": "必須フィールド",
"field.unknown": "不明なフィールド",
"dashboard.chatbot.answer.answer": "回答",
"dashboard.chatbot.answer.resources": "参考",
"dashboard.chatbot.answer.warning": "回答が正しくない場合もあります。内容がおかしいと思われる場合には、公式ドキュメントを確認してください。",
"dashboard.chatbot.chatbot.loading": "アシスタントを起動中",
"dashboard.chatbot.chatbot.ready": "準備ができました。何について知りたいですか?",
"dashboard.chatbot.chatbox.placeholder": "Front Matterの設定方法は",
"dashboard.chatbot.header.heading": "Front Matter AIに質問する",
"dashboard.chatbot.header.description": "このAIはmendable.aiをベースに公式ドキュメントがチューニングされており、Front Matter関連のクエリを理解してあなたをアシストします。何でも聞いてください",
"dashboard.common.choiceButton.open": "オプションを開く",
"dashboard.contents.contentActions.actionMenuButton.title": "メニュー",
"dashboard.contents.contentActions.menuItem.view": "開く",
"dashboard.contents.contentActions.alert.title": "削除: {0}",
"dashboard.contents.contentActions.alert.description": "本当に\"{0}\"を削除しますか?",
"dashboard.contents.item.invalidTitle": "<無効なタイトル>",
"dashboard.contents.item.invalidDescription": "<無効なディスクリプション>",
"dashboard.contents.list.title": "タイトル",
"dashboard.contents.list.date": "日付",
"dashboard.contents.list.status": "ステータス",
"dashboard.contents.overview.noMarkdown": "Markdownファイルはありません",
"dashboard.contents.overview.noFolders": "プロジェクト内の記事用フォルダーを登録して、Front Matterが記事を見つけられるようにしてください。",
"dashboard.contents.status.draft": "下書き",
"dashboard.contents.status.published": "公開済み",
"dashboard.dataView.dataForm.modify": "エントリーを編集",
"dashboard.dataView.dataForm.add": "エントリーを作成",
"dashboard.dataView.dataView.select": "データタイプを選択",
"dashboard.dataView.dataView.title": "\"{0}\"のエントリー",
"dashboard.dataView.dataView.add": "新規エントリーを追加",
"dashboard.dataView.dataView.empty": "\"{0}\"データにはエントリーがありません",
"dashboard.dataView.dataView.createOrModify": "\"{0}\"のエントリーを作成、または編集する",
"dashboard.dataView.dataView.getStarted": "データタイプを選択して開始する",
"dashboard.dataView.dataView.noDataFiles": "データファイルが見つかりませんでした",
"dashboard.dataView.dataView.getStarted.link": "データファイルの利用方法について確認する",
"dashboard.dataView.emptyView.heading": "最初にデータタイプを選んでください",
"dashboard.dataView.sortableItem.editButton.title": "\"{0}\"を編集する",
"dashboard.dataView.sortableItem.deleteButton.title": "\"{0}\"を削除する",
"dashboard.dataView.sortableItem.alert.title": "データアイテムを削除",
"dashboard.dataView.sortableItem.alert.description": "本当にこのデータアイテムを削除しますか?",
"dashboard.errorView.description": "ダッシュボードを一旦閉じてからやり直してください。",
"dashboard.header.breadcrumb.home": "ホーム",
"dashboard.header.clearFilters.title": "フィルター・グループ・並べ替えを解除",
"dashboard.header.filter.default": "なし",
"dashboard.header.folders.default": "全ての記事タイプ",
"dashboard.header.folders.menuButton.showing": "表示",
"dashboard.header.grouping.option.none": "なし",
"dashboard.header.grouping.option.year": "公開年",
"dashboard.header.grouping.option.draft": "下書き/公開済み",
"dashboard.header.grouping.menuButton.label": "グループ",
"dashboard.header.navigation.allArticles": "全ての記事",
"dashboard.header.navigation.published": "公開済み",
"dashboard.header.navigation.draft": "下書き",
"dashboard.header.header.createContent": "新しい記事を作成",
"dashboard.header.header.createByContentType": "記事タイプから作成",
"dashboard.header.header.createByTemplate": "テンプレートから作成",
"dashboard.header.pagination.first": "最初",
"dashboard.header.pagination.previous": "前へ",
"dashboard.header.pagination.next": "次へ",
"dashboard.header.pagination.last": "最後",
"dashboard.header.paginationStatus.text": "{0}{1}件目(全{2}件中)を表示中",
"dashboard.header.projectSwitcher.label": "プロジェクト",
"dashboard.header.refreshDashboard.label": "ダッシュボードを再読み込み",
"dashboard.header.sorting.lastModified.asc": "最終更新日(昇順)",
"dashboard.header.sorting.lastModified.desc": "最終更新日(降順)",
"dashboard.header.sorting.filename.asc": "ファイル名(昇順)",
"dashboard.header.sorting.filename.desc": "ファイル名(降順)",
"dashboard.header.sorting.published.asc": "公開日(昇順)",
"dashboard.header.sorting.published.desc": "公開日(降順)",
"dashboard.header.sorting.size.asc": "サイズ(昇順)",
"dashboard.header.sorting.size.desc": "サイズ(降順)",
"dashboard.header.sorting.caption.asc": "キャプション(昇順)",
"dashboard.header.sorting.caption.desc": "キャプション(降順)",
"dashboard.header.sorting.alt.asc": "代替テキスト(昇順)",
"dashboard.header.sorting.alt.desc": "代替テキスト(降順)",
"dashboard.header.sorting.label": "並べ替え",
"dashboard.header.startup.label": "起動時に表示",
"dashboard.header.tabs.contents": "記事",
"dashboard.header.tabs.media": "メディア",
"dashboard.header.tabs.snippets": "スニペット",
"dashboard.header.tabs.data": "データ",
"dashboard.header.tabs.taxonomies": "タクソノミー",
"dashboard.header.viewSwitch.toGrid": "グリッド表示",
"dashboard.header.viewSwitch.toList": "リスト表示",
"dashboard.layout.sponsor.support.msg": "Front Matterをサポートする",
"dashboard.layout.sponsor.review.label": "評価する",
"dashboard.layout.sponsor.review.msg": "Front Matterを評価する",
"dashboard.media.common.title": "タイトル",
"dashboard.media.common.caption": "キャプション",
"dashboard.media.common.alt": "代替テキスト",
"dashboard.media.common.size": "サイズ",
"dashboard.media.dialog.title": "ファイルの詳細",
"dashboard.media.panel.close": "パネルを閉じる",
"dashboard.media.metadata.panel.title": "メタデータを編集",
"dashboard.media.metadata.panel.description": "ファイルにメタデータを設定してください。",
"dashboard.media.metadata.panel.field.fileName": "ファイル名",
"dashboard.media.metadata.panel.form.metadata.title": "メタデータ",
"dashboard.media.metadata.panel.form.information.title": "詳細",
"dashboard.media.metadata.panel.form.information.createdDate": "作成日",
"dashboard.media.metadata.panel.form.information.modifiedDate": "最終更新日",
"dashboard.media.metadata.panel.form.information.dimensions": "ディメンション",
"dashboard.media.metadata.panel.form.information.folder": "フォルダー",
"dashboard.media.folderCreation.hexo.create": "Assetフォルダーを作成",
"dashboard.media.folderCreation.folder.create": "新規フォルダーを作成",
"dashboard.media.item.quickAction.insert.field": "この画像を\"{0}\"フィールドに追加",
"dashboard.media.item.quickAction.insert.markdown": "画像をMarkdown記法で挿入",
"dashboard.media.item.quickAction.copy.path": "ファイルパスをコピー",
"dashboard.media.item.quickAction.delete": "ファイルを削除",
"dashboard.media.item.menuItem.edit.metadata": "メタデータを編集",
"dashboard.media.item.menuItem.insert.image": "画像を挿入",
"dashboard.media.item.menuItem.reveal.media": "メディアの場所を表示",
"dashboard.media.item.infoDialog.snippet.description": "このメディアに適用するメディア用スニペットを選択してください。",
"dashboard.media.item.alert.delete.description": "本当にこのファイルを {0} から削除しますか?",
"dashboard.media.media.description": "記事に挿入するメディアファイルを選択してください。",
"dashboard.media.media.dragAndDrop": "デスクトップから画像をドラッグ&ドロップして、アップロード後に選択することもできます。",
"dashboard.media.media.folder.upload": "{0}にアップロードする",
"dashboard.media.media.folder.default": "フォルダーが選択されていません。ここにドロップされた画像は、{0}へ追加されます。",
"dashboard.media.media.placeholder": "メディアファイルはありません。Shiftキーを押しながら、新規ファイルをドラックドロップで追加することができます。",
"dashboard.media.media.contentFolder": "記事フォルダー",
"dashboard.media.media.publicFolder": "Publicフォルダー",
"dashboard.media.mediaHeaderTop.searchbox.placeholder": "フォルダー内を検索",
"dashboard.media.mediaSnippetForm.formDialog.title": "メディアを挿入: {0}",
"dashboard.media.mediaSnippetForm.formDialog.description": "メディアファイル\"{0}\"を現在の記事に挿入する",
"dashboard.preview.input.placeholder": "URLを入力",
"dashboard.preview.button.navigate.title": "ナビゲーション",
"dashboard.preview.button.refresh.title": "更新",
"dashboard.preview.button.open.title": "開く",
"dashboard.snippetsView.item.quickAction.editSnippet": "スニペットを編集",
"dashboard.snippetsView.item.quickAction.deleteSnippet": "スニペットを削除",
"dashboard.snippetsView.item.quickAction.viewSnippet": "スニペットファイルの表示",
"dashboard.snippetsView.item.insert.formDialog.title": "\"{0}\"スニペットの追加",
"dashboard.snippetsView.item.insert.formDialog.description": "\"{0}\"スニペットを現在の記事に追加します",
"dashboard.snippetsView.item.edit.formDialog.title": "\"{0}\"スニペットの編集",
"dashboard.snippetsView.item.edit.formDialog.description": "\"{0}\"スニペットの編集",
"dashboard.snippetsView.item.alert.title": "\"{0}\"スニペットを削除",
"dashboard.snippetsView.item.alert.description": "本当に\"{0}\"スニペットを削除しますか?",
"dashboard.snippetsView.newForm.snippetInput.title.placeholder": "スニペットのタイトル",
"dashboard.snippetsView.newForm.snippetInput.description.label": "概要",
"dashboard.snippetsView.newForm.snippetInput.description.placeholder": "スニペットの概要",
"dashboard.snippetsView.newForm.snippetInput.snippet.label": "スニペット",
"dashboard.snippetsView.newForm.snippetInput.snippet.placeholder": "スニペットのコード",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.label": "メディア用スニペットですか?",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.checkbox.label": "メディア用スニペット",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.checkbox.description": "このスニペットをメディアファイル挿入時に利用",
"dashboard.snippetsView.newForm.snippetInput.docsButton.title": "メディア用スニペットのプレースホルダーについて読む",
"dashboard.snippetsView.newForm.snippetInput.docsButton.description": "スニペットに設定可能なプレースホルダーをドキュメントで確認",
"dashboard.snippetsView.snippets.ariaLabel": "スニペット ヘッダー",
"dashboard.snippetsView.snippets.button.create": "新規スニペットを作成",
"dashboard.snippetsView.snippets.select.description": "挿入するスニペットを選択してください。",
"dashboard.snippetsView.snippets.empty.message": "スニペットはありません",
"dashboard.snippetsView.snippets.readMore": "スニペットの使い方を読む",
"dashboard.snippetsView.snippets.formDialog.title": "新規スニペットを作成",
"dashboard.steps.stepsToGetStarted.button.addFolder.title": "Front Matterに記事フォルダーとして登録",
"dashboard.steps.stepsToGetStarted.initializeProject.name": "プロジェクトの初期設定",
"dashboard.steps.stepsToGetStarted.initializeProject.description": "Front Matter CMSに必要な設定ファイルを作成します。クリックして開始してください。",
"dashboard.steps.stepsToGetStarted.framework.name": "フレームワークを設定",
"dashboard.steps.stepsToGetStarted.framework.description": "静的サイトジェネレーターまたはフレームワークを選択して、必要なセッティングを追加します。",
"dashboard.steps.stepsToGetStarted.framework.select": "フレームワークを選択",
"dashboard.steps.stepsToGetStarted.framework.select.other": "その他",
"dashboard.steps.stepsToGetStarted.contentFolders.name": "記事ファイルのフォルダーを登録",
"dashboard.steps.stepsToGetStarted.contentFolders.description": "記事ファイルの保存フォルダーを追加してください。フォルダーが設定されると、フォルダー内の記事ファイルがFront Matterでリスト化され、新規記事ファイルを追加できるようになります。",
"dashboard.steps.stepsToGetStarted.contentFolders.label": "記事ファイルを含むフォルダー",
"dashboard.steps.stepsToGetStarted.contentFolders.information.description": "フォルダーの登録は、エクスプローラーでフォルダー名を右クリックして「フォルダーを登録」を選択することでも可能です。",
"dashboard.steps.stepsToGetStarted.tags.name": "全てのタグとカテゴリーをインポート(オプション)",
"dashboard.steps.stepsToGetStarted.tags.description": "Front Matterに記事用フォルダーが登録されました。記事から全てのタグとカテゴリーをインポートしますか",
"dashboard.steps.stepsToGetStarted.showDashboard.name": "ダッシュボードを開く",
"dashboard.steps.stepsToGetStarted.showDashboard.description": "全ての設定が終わると、ダッシュボードが表示できるようになります。",
"dashboard.taxonomyView.button.add.title": "\"{0}\"をタクソノミーに追加",
"dashboard.taxonomyView.button.edit.title": "\"{0}\"を編集",
"dashboard.taxonomyView.button.merge.title": "\"{0}\"をマージ",
"dashboard.taxonomyView.button.move.title": "他のタクソノミーへ移行",
"dashboard.taxonomyView.button.delete.title": "\"{0}\"を削除",
"dashboard.taxonomyView.taxonomyLookup.button.title": "{1}\"{0}\"の記事一覧を表示",
"dashboard.taxonomyView.taxonomyManager.description": "サイト内{0}の新規作成・編集・コマンド",
"dashboard.taxonomyView.taxonomyManager.button.create": "新規{0}を作成",
"dashboard.taxonomyView.taxonomyManager.table.heading.name": "名前",
"dashboard.taxonomyView.taxonomyManager.table.heading.count": "投稿数",
"dashboard.taxonomyView.taxonomyManager.table.heading.action": "コマンド",
"dashboard.taxonomyView.taxonomyManager.table.row.empty": "{0}はありません",
"dashboard.taxonomyView.taxonomyManager.table.unmapped.title": "設定ファイルに見つかりません",
"dashboard.taxonomyView.taxonomyView.navigationBar.title": "タクソノミーを選択",
"dashboard.taxonomyView.taxonomyView.button.import": "タクソノミーをインポート",
"dashboard.taxonomyView.taxonomyView.navigationItem.tags": "タグ",
"dashboard.taxonomyView.taxonomyView.navigationItem.categories": "カテゴリー",
"dashboard.unkownView.title": "表示出来る画面がありません",
"dashboard.unkownView.description": "存在しない画面で終了してしまったようです。ダッシュボードを再度開きなおしてください。",
"dashboard.welcomeScreen.title": "Front Matterで静的サイトを管理しよう",
"dashboard.welcomeScreen.thanks": "Front Matterをお使いいただきありがとうございます",
"dashboard.welcomeScreen.description": "私たちはFront Matterをより使いやすくするため、日々努力しています。ご質問やご提案など、GitHubまでお気軽にお問い合わせください。",
"dashboard.welcomeScreen.link.github.title": "GitHub",
"dashboard.welcomeScreen.link.github.label": "GitHub / ドキュメント",
"dashboard.welcomeScreen.link.sponsor.title": "スポンサーになる",
"dashboard.welcomeScreen.link.sponsor.label": "スポンサー",
"dashboard.welcomeScreen.link.review.title": "評価する",
"dashboard.welcomeScreen.link.review.label": "評価する",
"dashboard.welcomeScreen.actions.heading": "以下の手順に従って、この拡張機能をスタートさせてください。",
"dashboard.welcomeScreen.actions.description": "サイドパネルからもFront Matterを利用できます。サイドパネルでは、各コンテンツに合った具体的なコマンドが実行可能です。",
"dashboard.welcomeScreen.actions.thanks": "Front Matterをお楽しみください",
"panel.contentType.contentTypeValidator.title": "記事タイプ",
"panel.contentType.contentTypeValidator.hint": "記事タイプのフィールドは設定と異なります。この記事の記事タイプを、作成・更新または設定しますか?",
"panel.contentType.contentTypeValidator.button.create": "新しい記事タイプを作成",
"panel.contentType.contentTypeValidator.button.add": "この記事タイプの設定にないフィールドを追加",
"panel.contentType.contentTypeValidator.button.change": "このファイルの記事タイプを変更",
"panel.dataBlock.dataBlockField.group.selected.edit": "編集: {0}",
"panel.dataBlock.dataBlockField.group.selected.create": "新規{0}を作成",
"panel.dataBlock.dataBlockField.group.select": "グループを選択",
"panel.dataBlock.dataBlockField.add": "{0}を追加",
"panel.dataBlock.dataBlockRecord.edit": "レコードを編集",
"panel.dataBlock.dataBlockRecord.delete": "レコードを削除",
"panel.dataBlock.dataBlockRecords.label": "レコード",
"panel.dataBlock.dataBlockSelector.label": "ブロックタイプ",
"panel.errorBoundary.fieldBoundary.label": "フィールドの表示に失敗しました",
"panel.fields.choiceField.select": "{0}を選択",
"panel.fields.choiceField.clear": "値をクリア",
"panel.fields.contentTypeRelationshipField.loading": "読み込み中...",
"panel.fields.dateTimeField.button.pick": "日付を選択",
"panel.fields.dateTimeField.time": "時刻",
"panel.fields.fieldMessage.required": "{0}は必須フィールドです",
"panel.fields.fileField.delete": "ファイルを削除",
"panel.fields.fileField.add": "{0}を追加",
"panel.fields.imageFallback.label": "画像を読み込めませんでした。",
"panel.fields.listField.edit": "レコードを編集",
"panel.fields.listField.delete": "レコードを削除",
"panel.fields.previewImage.remove": "画像を削除",
"panel.fields.previewImageField.add": "{0}を追加",
"panel.fields.slugField.update": "更新が可能",
"panel.fields.slugField.generate": "スラッグを生成",
"panel.fields.textField.ai.message": "Front Matter AIに{0}を提案してもらう",
"panel.fields.textField.ai.generate": "提案を生成中...",
"panel.fields.textField.loading": "読み込み中",
"panel.fields.textField.limit": "値が上限を超えています。{0}",
"panel.fields.wrapperField.unknown": "不明なフィールド: {0}",
"panel.actions.title": "コマンド",
"panel.articleDetails.title": "詳細",
"panel.articleDetails.type": "項目",
"panel.articleDetails.total": "数",
"panel.articleDetails.headings": "見出し",
"panel.articleDetails.paragraphs": "パラグラフ",
"panel.articleDetails.internalLinks": "内部リンク",
"panel.articleDetails.externalLinks": "外部リンク",
"panel.articleDetails.images": "画像",
"panel.baseView.initialize": "プロジェクトの初期設定",
"panel.baseView.actions.title": "コマンド",
"panel.baseView.action.openDashboard": "ダッシュボードを開く",
"panel.baseView.action.openPreview": "プレビューを開く",
"panel.baseView.action.createContent": "新しい記事を作成",
"panel.baseView.empty": "他の操作を見るには、ファイルを開いてください。",
"panel.fileList.label.singular": "ファイル",
"panel.fileList.label.plural": "ファイル",
"panel.folderAndFiles.title": "最近の更新",
"panel.globalSettings.title": "一般設定",
"panel.globalSettings.action.modifiedDate.label": "最終更新日",
"panel.globalSettings.action.modifiedDate.description": "最終更新日を自動で更新",
"panel.globalSettings.action.frontMatter.label": "Front Matterのハイライト",
"panel.globalSettings.action.frontMatter.description": "Front Matterをハイライトする",
"panel.globalSettings.action.preview.label": "ローカルプレビュー",
"panel.globalSettings.action.preview.placeholder": "例: {0}",
"panel.globalSettings.action.server.label": "ローカルサーバーのコマンド",
"panel.globalSettings.action.server.placeholder": "例: {0}",
"panel.metadata.title": "メタデータ",
"panel.otherActions.title": "他のコマンド",
"panel.otherActions.writingSettings.enabled": "ライティング設定が有効",
"panel.otherActions.writingSettings.disabled": "ライティング設定を有効化",
"panel.otherActions.centerMode": "センターモードの切り替え",
"panel.otherActions.createTemplate": "テンプレートを作成",
"panel.otherActions.revealFile": "ファイルをフォルダーで表示",
"panel.otherActions.openProject": "プロジェクトフォルダーを表示",
"panel.otherActions.documentation": "ドキュメントを開く",
"panel.otherActions.settings": "設定方法の概要",
"panel.otherActions.issue": "問題を報告",
"panel.preview.title": "プレビューを表示",
"panel.publishAction.publish": "公開",
"panel.publishAction.unpublish": "下書きに戻す",
"panel.seoDetails.recommended": "🚧: Recommended",
"panel.seoKeywordInfo.density": "キーワード出現率 {0} *",
"panel.seoKeywordInfo.validInfo.label": "見出しへの利用",
"panel.seoKeywordInfo.validInfo.content": "本文",
"panel.seoKeywords.title": "キーワード",
"panel.seoKeywords.header.keyword": "キーワード",
"panel.seoKeywords.header.details": "詳細",
"panel.seoKeywords.density": "* キーワード出現率は通常1~1.5%で十分です。",
"panel.seoStatus.title": "推奨項目",
"panel.seoStatus.header.property": "項目",
"panel.seoStatus.header.length": "長さ",
"panel.seoStatus.header.valid": "有効",
"panel.seoStatus.seoFieldInfo.characters": "{0} 文字",
"panel.seoStatus.seoFieldInfo.words": "{0} 語",
"panel.seoStatus.seoFieldInfo.article": "記事の長さ",
"panel.seoStatus.collapsible.title": "SEO対策",
"panel.seoStatus.required": "{0}か{1}は必須です。",
"panel.slugAction.title": "スラッグを最適化",
"panel.spinner.loading": "読み込み中...",
"panel.startServerbutton.start": "サーバーを起動",
"panel.startServerbutton.stop": "サーバーを停止",
"panel.tag.add": "\"{0}\"を設定に追加",
"panel.tagPicker.inputPlaceholder.empty": "{0}を選択",
"panel.tagPicker.inputPlaceholder.disabled": "{0}の上限数に達しました",
"panel.tagPicker.ai.suggest": "Front Matter AIに{0}を提案してもらう",
"panel.tagPicker.ai.generating": "提案を生成中...",
"panel.tagPicker.limit": "上限数: {0}",
"panel.tagPicker.unkown": "不明なタグを追加",
"panel.tags.tag.warning": "\"{0}\"は設定に保存されていません。削除すると復元できませんのでご注意ください。",
"panel.viewPanel.mediaInsert": "ダッシュボードのメディア管理画面から、利用したい画像を選択してください。",
"dashboard.steps.stepsToGetStarted.assetsFolder.name": "アセットフォルダーの場所はどこですか?",
"dashboard.steps.stepsToGetStarted.assetsFolder.description": "記事のメディアファイルを保存するためのフォルダーを選択してください。",
"dashboard.steps.stepsToGetStarted.assetsFolder.public.title": "'public'フォルダーを使用する",
"dashboard.steps.stepsToGetStarted.assetsFolder.assets.title": "Astroアセットフォルダー(src/assets)を使用する",
"dashboard.steps.stepsToGetStarted.assetsFolder.other.description": "別のフォルダを設定する場合は、frontmatter.jsonファイルで手動で行うことができます。"
}

426
l10n/bundle.l10n.json Normal file
View File

@@ -0,0 +1,426 @@
{
"common.add": "Add",
"common.edit": "Edit",
"common.delete": "Delete",
"common.cancel": "Cancel",
"common.clear": "Clear",
"common.clear.value": "Clear value",
"common.search": "Search",
"common.save": "Save",
"common.menu": "Menu",
"common.insert": "Insert",
"common.insert.snippet": "Insert snippet",
"common.title": "Title",
"common.description": "Description",
"common.retry": "Retry",
"common.update": "Update",
"common.information": "Info",
"common.important": "Important",
"common.sync": "Sync",
"common.slug": "Slug",
"common.support": "Support",
"common.remove.value": "Remove {0}",
"common.error.message": "Sorry, something went wrong.",
"developer.title": "Developer mode",
"developer.reload.title": "Reload the dashboard",
"developer.reload.label": "Reload",
"developer.devTools.title": "Open the DevTools",
"developer.devTools.label": "DevTools",
"field.required": "Required field",
"field.unknown": "Unknown field",
"dashboard.chatbot.answer.answer": "Answer",
"dashboard.chatbot.answer.resources": "Resources",
"dashboard.chatbot.answer.warning": "Warning: Anwers might be wrong. In case of doubt, please consult the docs.",
"dashboard.chatbot.chatbot.loading": "Assistent is getting ready",
"dashboard.chatbot.chatbot.ready": "I'm ready, what do you want to know?",
"dashboard.chatbot.chatbox.placeholder": "How can I configure Front Matter?",
"dashboard.chatbot.header.heading": "Ask Front Matter AI",
"dashboard.chatbot.header.description": "Our AI, powered by mendable.ai, has processed the documentation and can assist you with any queries regarding Front Matter. Go ahead and ask away!",
"dashboard.common.choiceButton.open": "Open options",
"dashboard.contents.contentActions.actionMenuButton.title": "Menu",
"dashboard.contents.contentActions.menuItem.view": "View",
"dashboard.contents.contentActions.alert.title": "Delete: {0}",
"dashboard.contents.contentActions.alert.description": "Are you sure you want to delete the \"{0}\" content?",
"dashboard.contents.item.invalidTitle": "<invalid title>",
"dashboard.contents.item.invalidDescription": "<invalid description>",
"dashboard.contents.list.title": "Title",
"dashboard.contents.list.date": "Date",
"dashboard.contents.list.status": "Status",
"dashboard.contents.overview.noMarkdown": "No Markdown to show",
"dashboard.contents.overview.noFolders": "Make sure you registered a content folder in your project to let Front Matter find the contents.",
"dashboard.contents.status.draft": "Draft",
"dashboard.contents.status.published": "Published",
"dashboard.dataView.dataForm.modify": "Modify the data",
"dashboard.dataView.dataForm.add": "Add new data",
"dashboard.dataView.dataView.select": "Select your data type",
"dashboard.dataView.dataView.title": "Your {0} data items",
"dashboard.dataView.dataView.add": "Add a new entry",
"dashboard.dataView.dataView.empty": "No {0} data entries found",
"dashboard.dataView.dataView.createOrModify": "Create or modify your {0} data",
"dashboard.dataView.dataView.getStarted": "Select a data type to get started",
"dashboard.dataView.dataView.noDataFiles": "No data files found",
"dashboard.dataView.dataView.getStarted.link": "Read more to get started using data files",
"dashboard.dataView.emptyView.heading": "Select your date type first",
"dashboard.dataView.sortableItem.editButton.title": "Edit \"{0}\"",
"dashboard.dataView.sortableItem.deleteButton.title": "Delete \"{0}\"",
"dashboard.dataView.sortableItem.alert.title": "Delete data entry",
"dashboard.dataView.sortableItem.alert.description": "Are you sure you want to delete the data entry?",
"dashboard.errorView.description": "Please close the dashboard and try again.",
"dashboard.header.breadcrumb.home": "Home",
"dashboard.header.clearFilters.title": "Clear filters, grouping, and sorting",
"dashboard.header.filter.default": "No filter",
"dashboard.header.folders.default": "All types",
"dashboard.header.folders.menuButton.showing": "Showing",
"dashboard.header.grouping.option.none": "None",
"dashboard.header.grouping.option.year": "Year",
"dashboard.header.grouping.option.draft": "Draft/Published",
"dashboard.header.grouping.menuButton.label": "Group by",
"dashboard.header.navigation.allArticles": "All articles",
"dashboard.header.navigation.published": "Published",
"dashboard.header.navigation.draft": "In draft",
"dashboard.header.header.createContent": "Create content",
"dashboard.header.header.createByContentType": "Create by content type",
"dashboard.header.header.createByTemplate": "Create by template",
"dashboard.header.pagination.first": "First",
"dashboard.header.pagination.previous": "Previous",
"dashboard.header.pagination.next": "next",
"dashboard.header.pagination.last": "Last",
"dashboard.header.paginationStatus.text": "Showing {0} to {1} of {2} results",
"dashboard.header.projectSwitcher.label": "project",
"dashboard.header.refreshDashboard.label": "Refresh dashboard",
"dashboard.header.sorting.lastModified.asc": "Last modified (asc)",
"dashboard.header.sorting.lastModified.desc": "Last modified (desc)",
"dashboard.header.sorting.filename.asc": "By filename (asc)",
"dashboard.header.sorting.filename.desc": "By filename (desc)",
"dashboard.header.sorting.published.asc": "Published (asc)",
"dashboard.header.sorting.published.desc": "Published (desc)",
"dashboard.header.sorting.size.asc": "Size (asc)",
"dashboard.header.sorting.size.desc": "Size (desc)",
"dashboard.header.sorting.caption.asc": "Caption (asc)",
"dashboard.header.sorting.caption.desc": "Caption (desc)",
"dashboard.header.sorting.alt.asc": "Alt (asc)",
"dashboard.header.sorting.alt.desc": "Alt (desc)",
"dashboard.header.sorting.label": "Sort by",
"dashboard.header.startup.label": "Open on startup?",
"dashboard.header.tabs.contents": "Contents",
"dashboard.header.tabs.media": "Media",
"dashboard.header.tabs.snippets": "Snippets",
"dashboard.header.tabs.data": "data",
"dashboard.header.tabs.taxonomies": "Taxonomies",
"dashboard.header.viewSwitch.toGrid": "Change to grid",
"dashboard.header.viewSwitch.toList": "Change to list",
"dashboard.layout.sponsor.support.msg": "Support Front Matter",
"dashboard.layout.sponsor.review.label": "Review",
"dashboard.layout.sponsor.review.msg": "Review Front Matter",
"dashboard.media.common.title": "Title",
"dashboard.media.common.caption": "Caption",
"dashboard.media.common.alt": "Alternate text",
"dashboard.media.common.size": "Size",
"dashboard.media.dialog.title": "View details",
"dashboard.media.panel.close": "Close panel",
"dashboard.media.metadata.panel.title": "Update metadata",
"dashboard.media.metadata.panel.description": "Please specify the metadata you want to set for the file.",
"dashboard.media.metadata.panel.field.fileName": "Filename",
"dashboard.media.metadata.panel.form.metadata.title": "Metadata",
"dashboard.media.metadata.panel.form.information.title": "Information",
"dashboard.media.metadata.panel.form.information.createdDate": "Created",
"dashboard.media.metadata.panel.form.information.modifiedDate": "Last modified",
"dashboard.media.metadata.panel.form.information.dimensions": "Dimensions",
"dashboard.media.metadata.panel.form.information.folder": "Folder",
"dashboard.media.folderCreation.hexo.create": "Create post asset folder",
"dashboard.media.folderCreation.folder.create": "Create new folder",
"dashboard.media.item.quickAction.insert.field": "Insert image for your \"{0}\" field",
"dashboard.media.item.quickAction.insert.markdown": "Insert image with markdown markup",
"dashboard.media.item.quickAction.copy.path": "Copy media path",
"dashboard.media.item.quickAction.delete": "Delete media file",
"dashboard.media.item.menuItem.edit.metadata": "Edit metadata",
"dashboard.media.item.menuItem.insert.image": "Insert image",
"dashboard.media.item.menuItem.reveal.media": "Reveal media",
"dashboard.media.item.infoDialog.snippet.description": "Select the media snippet to use for the current media file.",
"dashboard.media.item.alert.delete.description": "Are you sure you want to delete the file from the {0} folder?",
"dashboard.media.media.description": "Select the media file to add to your content.",
"dashboard.media.media.dragAndDrop": "You can also drag and drop images from your desktop and select them once uploaded.",
"dashboard.media.media.folder.upload": "Upload to {0}",
"dashboard.media.media.folder.default": "No folder selected, files you drop will be added to the {0} folder",
"dashboard.media.media.placeholder": "No media files to show. You can drag &amp; drop new files by holding your [shift] key.",
"dashboard.media.media.contentFolder": "Content folder",
"dashboard.media.media.publicFolder": "Public folder",
"dashboard.media.mediaHeaderTop.searchbox.placeholder": "Search in folder",
"dashboard.media.mediaSnippetForm.formDialog.title": "Insert media: {0}",
"dashboard.media.mediaSnippetForm.formDialog.description": "Insert the {0} media file into the current article",
"dashboard.preview.input.placeholder": "Enter a URL",
"dashboard.preview.button.navigate.title": "Navigate",
"dashboard.preview.button.refresh.title": "Refresh",
"dashboard.preview.button.open.title": "Open",
"dashboard.snippetsView.item.quickAction.editSnippet": "Edit snippet",
"dashboard.snippetsView.item.quickAction.deleteSnippet": "Delete snippet",
"dashboard.snippetsView.item.quickAction.viewSnippet": "View snippet file",
"dashboard.snippetsView.item.insert.formDialog.title": "Insert snippet: {0}",
"dashboard.snippetsView.item.insert.formDialog.description": "Insert the {0} snippet into the current article",
"dashboard.snippetsView.item.edit.formDialog.title": "Edit snippet: {0}",
"dashboard.snippetsView.item.edit.formDialog.description": "Edit the {0} snippet",
"dashboard.snippetsView.item.alert.title": "Delete snippet: {0}",
"dashboard.snippetsView.item.alert.description": "Are you sure you want to delete the {0} snippet?",
"dashboard.snippetsView.newForm.snippetInput.title.placeholder": "Snippet title",
"dashboard.snippetsView.newForm.snippetInput.description.label": "Description",
"dashboard.snippetsView.newForm.snippetInput.description.placeholder": "Snippet description",
"dashboard.snippetsView.newForm.snippetInput.snippet.label": "Snippet",
"dashboard.snippetsView.newForm.snippetInput.snippet.placeholder": "Snippet content",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.label": "Is a media snippet?",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.checkbox.label": "Media snippet",
"dashboard.snippetsView.newForm.snippetInput.isMediaSnippet.checkbox.description": "Use the current snippet for inserting media files into your content.",
"dashboard.snippetsView.newForm.snippetInput.docsButton.title": "Read more on using media snippet placeholders",
"dashboard.snippetsView.newForm.snippetInput.docsButton.description": "Check our media snippet placeholders documentation to know which placeholders you can use.",
"dashboard.snippetsView.snippets.ariaLabel": "Snippets header",
"dashboard.snippetsView.snippets.button.create": "Create new snippet",
"dashboard.snippetsView.snippets.select.description": "Select the snippet to add to your content.",
"dashboard.snippetsView.snippets.empty.message": "No snippets found",
"dashboard.snippetsView.snippets.readMore": "Read more to get started with snippets",
"dashboard.snippetsView.snippets.formDialog.title": "Create a snippet",
"dashboard.steps.stepsToGetStarted.button.addFolder.title": "Add as a content folder to Front Matter",
"dashboard.steps.stepsToGetStarted.initializeProject.name": "Initialize project",
"dashboard.steps.stepsToGetStarted.initializeProject.description": "Initialize the project will create the required files and folders for using the Front Matter CMS. Start by clicking on this action.",
"dashboard.steps.stepsToGetStarted.framework.name": "Framework presets",
"dashboard.steps.stepsToGetStarted.framework.description": "Select your site-generator or framework to prefill some of the recommended settings.",
"dashboard.steps.stepsToGetStarted.framework.select": "Select your framework",
"dashboard.steps.stepsToGetStarted.framework.select.other": "other",
"dashboard.steps.stepsToGetStarted.assetsFolder.name": "What is your assets folder?",
"dashboard.steps.stepsToGetStarted.assetsFolder.description": "Select the folder containing your assets. This folder will be used to store all your media files for your articles.",
"dashboard.steps.stepsToGetStarted.assetsFolder.public.title": "Use the 'public' folder",
"dashboard.steps.stepsToGetStarted.assetsFolder.assets.title": "Use the Astro assets folder (src/assets)",
"dashboard.steps.stepsToGetStarted.assetsFolder.other.description": "In case you want to configure another folder, you can do this manually in the frontmatter.json file.",
"dashboard.steps.stepsToGetStarted.contentFolders.name": "Register content folder(s)",
"dashboard.steps.stepsToGetStarted.contentFolders.description": "Add one of the folders we found in your project as a content folder. Once a folder is set, Front Matter can be used to list all contents and allow you to create content.",
"dashboard.steps.stepsToGetStarted.contentFolders.label": "Folders containing content:",
"dashboard.steps.stepsToGetStarted.contentFolders.information.description": "You can also perform this action by right-clicking on the folder in the explorer view, and selecting register folder",
"dashboard.steps.stepsToGetStarted.tags.name": "Import all tags and categories (optional)",
"dashboard.steps.stepsToGetStarted.tags.description": "Now that Front Matter knows all the content folders. Would you like to import all tags and categories from the available content?",
"dashboard.steps.stepsToGetStarted.showDashboard.name": "Show the dashboard",
"dashboard.steps.stepsToGetStarted.showDashboard.description": "Once all actions are completed, the dashboard can be loaded.",
"dashboard.taxonomyView.button.add.title": "Add {0} to taxonomy settings",
"dashboard.taxonomyView.button.edit.title": "Edit {0}",
"dashboard.taxonomyView.button.merge.title": "Merge {0}",
"dashboard.taxonomyView.button.move.title": "Move to another taxonomy type",
"dashboard.taxonomyView.button.delete.title": "Delete {0}",
"dashboard.taxonomyView.taxonomyLookup.button.title": "Show contents with {0} in {1}",
"dashboard.taxonomyView.taxonomyManager.description": "Create, edit, and manage the {0} of your site",
"dashboard.taxonomyView.taxonomyManager.button.create": "Create a new {0} value",
"dashboard.taxonomyView.taxonomyManager.table.heading.name": "Name",
"dashboard.taxonomyView.taxonomyManager.table.heading.count": "Count",
"dashboard.taxonomyView.taxonomyManager.table.heading.action": "Action",
"dashboard.taxonomyView.taxonomyManager.table.row.empty": "No {0} found",
"dashboard.taxonomyView.taxonomyManager.table.unmapped.title": "Missing in your settings",
"dashboard.taxonomyView.taxonomyView.navigationBar.title": "Select the taxonomy",
"dashboard.taxonomyView.taxonomyView.button.import": "Import taxonomy",
"dashboard.taxonomyView.taxonomyView.navigationItem.tags": "Tags",
"dashboard.taxonomyView.taxonomyView.navigationItem.categories": "Categories",
"dashboard.unkownView.title": "View does not exist",
"dashboard.unkownView.description": "You seem to have ended up on a view that doesn't exist. Please re-open the dashboard.",
"dashboard.welcomeScreen.title": "Manage your static site with Front Matter",
"dashboard.welcomeScreen.thanks": "Thank you for using Front Matter!",
"dashboard.welcomeScreen.description": "We try to aim to make Front Matter as easy to use as possible, but if you have any questions or suggestions. Please don't hesitate to reach out to us on GitHub.",
"dashboard.welcomeScreen.link.github.title": "GitHub",
"dashboard.welcomeScreen.link.github.label": "GitHub / Documentation",
"dashboard.welcomeScreen.link.sponsor.title": "Become a sponsor",
"dashboard.welcomeScreen.link.sponsor.label": "Sponsor",
"dashboard.welcomeScreen.link.review.title": "Write a review",
"dashboard.welcomeScreen.link.review.label": "Review",
"dashboard.welcomeScreen.actions.heading": "Perform the next steps to get you started with the extension",
"dashboard.welcomeScreen.actions.description": "You can also use the extension from the Front Matter side panel. There you will find the actions you can perform specifically for your pages.",
"dashboard.welcomeScreen.actions.thanks": "We hope you enjoy Front Matter!",
"panel.contentType.contentTypeValidator.title": "Content-type",
"panel.contentType.contentTypeValidator.hint": "We noticed field differences between the content-type and the front matter data. \n Would you like to create, update, or set the content-type for this content?",
"panel.contentType.contentTypeValidator.button.create": "Create content-type",
"panel.contentType.contentTypeValidator.button.add": "Add missing fields to content-type",
"panel.contentType.contentTypeValidator.button.change": "Change content-type of the file",
"panel.dataBlock.dataBlockField.group.selected.edit": "Editing: {0}",
"panel.dataBlock.dataBlockField.group.selected.create": "Create a new {0}",
"panel.dataBlock.dataBlockField.group.select": "Select a group",
"panel.dataBlock.dataBlockField.add": "Add {0}",
"panel.dataBlock.dataBlockRecord.edit": "Edit record",
"panel.dataBlock.dataBlockRecord.delete": "Delete record",
"panel.dataBlock.dataBlockRecords.label": "Records",
"panel.dataBlock.dataBlockSelector.label": "Block type",
"panel.errorBoundary.fieldBoundary.label": "Failed viewing the field",
"panel.fields.choiceField.select": "Select {0}",
"panel.fields.choiceField.clear": "Clear value",
"panel.fields.contentTypeRelationshipField.loading": "Fetching possible values...",
"panel.fields.dateTimeField.button.pick": "Pick your date",
"panel.fields.dateTimeField.time": "Time:",
"panel.fields.fieldMessage.required": "The {0} field is required",
"panel.fields.fileField.delete": "Delete file",
"panel.fields.fileField.add": "Add your {0}",
"panel.fields.imageFallback.label": "The image coundn't be loaded",
"panel.fields.listField.edit": "Edit record",
"panel.fields.listField.delete": "Delete record",
"panel.fields.previewImage.remove": "Remove image",
"panel.fields.previewImageField.add": "Add your {0}",
"panel.fields.slugField.update": "Update available",
"panel.fields.slugField.generate": "Generate slug",
"panel.fields.textField.ai.message": "Use Front Matter AI to suggest {0}",
"panel.fields.textField.ai.generate": "Generating suggestion...",
"panel.fields.textField.loading": "Loading field",
"panel.fields.textField.limit": "Field limit reached {0}",
"panel.fields.wrapperField.unknown": "Unkown field type: {0}",
"panel.actions.title": "Actions",
"panel.articleDetails.title": "More details",
"panel.articleDetails.type": "Type",
"panel.articleDetails.total": "Total",
"panel.articleDetails.headings": "Headings",
"panel.articleDetails.paragraphs": "Paragraphs",
"panel.articleDetails.internalLinks": "Internal links",
"panel.articleDetails.externalLinks": "External links",
"panel.articleDetails.images": "Images",
"panel.baseView.initialize": "Initialize project",
"panel.baseView.actions.title": "Actions",
"panel.baseView.action.openDashboard": "Open dashboard",
"panel.baseView.action.openPreview": "Open preview",
"panel.baseView.action.createContent": "Create content",
"panel.baseView.empty": "Open a file to see more actions",
"panel.fileList.label.singular": "file",
"panel.fileList.label.plural": "files",
"panel.folderAndFiles.title": "Recently modified",
"panel.globalSettings.title": "Global settings",
"panel.globalSettings.action.modifiedDate.label": "Modified date",
"panel.globalSettings.action.modifiedDate.description": "Auto-update modified date",
"panel.globalSettings.action.frontMatter.label": "Front Matter highlight",
"panel.globalSettings.action.frontMatter.description": "Highlight Front Matter",
"panel.globalSettings.action.preview.label": "Local preview",
"panel.globalSettings.action.preview.placeholder": "Example: {0}",
"panel.globalSettings.action.server.label": "Local server command",
"panel.globalSettings.action.server.placeholder": "Example: {0}",
"panel.metadata.title": "Metadata",
"panel.otherActions.title": "Other actions",
"panel.otherActions.writingSettings.enabled": "Writing settings enabled",
"panel.otherActions.writingSettings.disabled": "Enable writing settings",
"panel.otherActions.centerMode": "Toggle center mode",
"panel.otherActions.createTemplate": "Create template",
"panel.otherActions.revealFile": "Reveal file in folder",
"panel.otherActions.openProject": "Reveal project folder",
"panel.otherActions.documentation": "Open documentation",
"panel.otherActions.settings": "Settings overview",
"panel.otherActions.issue": "Report an issue",
"panel.preview.title": "Open preview",
"panel.publishAction.publish": "Publish",
"panel.publishAction.unpublish": "Revert to draft",
"panel.seoDetails.recommended": "Recommended",
"panel.seoKeywordInfo.density": "Keyword usage {0} *",
"panel.seoKeywordInfo.validInfo.label": "Used in heading(s)",
"panel.seoKeywordInfo.validInfo.content": "Content",
"panel.seoKeywords.title": "Keywords",
"panel.seoKeywords.header.keyword": "Keyword",
"panel.seoKeywords.header.details": "Details",
"panel.seoKeywords.density": "* A keyword density of 1-1.5% is sufficient in most cases.",
"panel.seoStatus.title": "Recommendations",
"panel.seoStatus.header.property": "Property",
"panel.seoStatus.header.length": "Length",
"panel.seoStatus.header.valid": "Valid",
"panel.seoStatus.seoFieldInfo.characters": "{0} chars",
"panel.seoStatus.seoFieldInfo.words": "{0} words",
"panel.seoStatus.seoFieldInfo.article": "Article length",
"panel.seoStatus.collapsible.title": "SEO Status",
"panel.seoStatus.required": "{0} or {1} is required.",
"panel.slugAction.title": "Optimize slug",
"panel.spinner.loading": "Loading...",
"panel.startServerbutton.start": "Start server",
"panel.startServerbutton.stop": "Stop server",
"panel.tag.add": "Add {0} to your settings",
"panel.tagPicker.inputPlaceholder.empty": "Pick your {0}",
"panel.tagPicker.inputPlaceholder.disabled": "You have reached the limit of {0}",
"panel.tagPicker.ai.suggest": "Use Front Matter AI to suggest {0}",
"panel.tagPicker.ai.generating": "Generating suggestions...",
"panel.tagPicker.limit": "Max.: {0}",
"panel.tagPicker.unkown": "Add the unknown tag",
"panel.tags.tag.warning": "Be aware, this tag \"{0}\" is not saved in your settings. Once removed, it will be gone forever.",
"panel.viewPanel.mediaInsert": "Continue in the media dashboard to select the image you want to insert."
}

BIN
new-features.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

BIN
optimizations.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

20982
package-lock.json generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

243
package.nls.de.json Normal file
View File

@@ -0,0 +1,243 @@
{
"command.frontMatter.project.switch": "Projekt wechseln",
"command.frontMatter.config.reload": "Konfiguration neu laden",
"command.frontMatter.authenticate": "Authentifizieren",
"command.frontMatter.contenttype.generate": "Content-Typ aus aktueller Datei generieren",
"command.frontMatter.contenttype.addMissingFields": "Fehlende Felder aus Front Matter zum Content-Typ hinzufügen",
"command.frontMatter.contenttype.setContentType": "Content-Typ für aktuelle Datei festlegen",
"command.frontMatter.markup.blockquote": "Blockzitat",
"command.frontMatter.markup.bold": "Fett",
"command.frontMatter.dashboard.close": "Dashboard schließen",
"command.frontMatter.markup.code": "Code",
"command.frontMatter.markup.codeblock": "Codeblock",
"command.frontMatter.markup.hyperlink": "Hyperlink",
"command.frontMatter.collapseSections": "Abschnitte ausblenden",
"command.frontMatter.initTemplate": "Template-Ordner initialisieren",
"command.frontMatter.createTemplate": "Template aus aktueller Datei erstellen",
"command.frontMatter.createCategory": "Kategorie erstellen",
"command.frontMatter.createContent": "Neuen Inhalt aus definiertem Content-Typ oder Template erstellen",
"command.frontMatter.createTag": "Tag erstellen",
"command.frontMatter.diagnostics": "Diagnoseprotokollierung",
"command.frontMatter.exportTaxonomy": "Alle Tags und Kategorien in Ihre Einstellungen exportieren",
"command.frontMatter.createFromTemplate": "Neuer Artikel aus Template",
"command.frontMatter.registerFolder": "Ordner registrieren",
"command.frontMatter.unregisterFolder": "Ordner deregistrieren",
"command.frontMatter.generateSlug": "Slug basierend auf Titel generieren",
"command.frontMatter.markup.heading": "Überschrift",
"command.frontMatter.init": "Projekt initialisieren",
"command.frontMatter.insertCategories": "Kategorien einfügen",
"command.frontMatter.insertMedia": "Medien in Ihren Inhalt einfügen",
"command.frontMatter.insertSnippet": "Snippet in Ihren Inhalt einfügen",
"command.frontMatter.insertTags": "Tags einfügen",
"command.frontMatter.markup.italic": "Kursiv",
"command.frontMatter.dashboard": "Dashboard öffnen",
"command.frontMatter.dashboard.data": "Daten-Dashboard öffnen",
"command.frontMatter.dashboard.media": "Medien-Dashboard öffnen",
"command.frontMatter.dashboard.snippets": "Snippets-Dashboard öffnen",
"command.frontMatter.dashboard.taxonomy": "Taxonomie-Dashboard öffnen",
"command.frontMatter.markup.orderedlist": "Geordnete Liste",
"command.frontMatter.markup.options": "Weitere Markup-Optionen",
"command.frontMatter.preview": "Inhalt anzeigen",
"command.frontMatter.chatbot": "Fragen Sie den Front Matter AI um Hilfe",
"command.frontMatter.promoteSettings": "Einstellungen von lokal auf Team-Ebene übertragen",
"command.frontMatter.remap": "Tag/Kategorie in allen Artikeln neu zuordnen oder entfernen",
"command.frontMatter.setLastModifiedDate": "Letztes Änderungsdatum festlegen",
"command.frontMatter.markup.strikethrough": "Durchgestrichen",
"command.frontMatter.mode.switch": "Modus wechseln",
"command.frontMatter.markup.tasklist": "Aufgabenliste",
"command.frontMatter.markup.unorderedlist": "Ungeordnete Liste",
"command.frontMatter.git.sync": "Synchronisieren",
"command.frontMatter.cache.clear": "Cache löschen",
"settings.configuration.title": "Front Matter: Verwendung von frontmatter.json für gemeinsame Team-Einstellungen",
"setting.frontMatter.projects.markdownDescription": "Geben Sie die Liste der Projekte an, die in Front Matter CMS geladen werden sollen. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.projects)",
"setting.frontMatter.projects.items.properties.name.markdownDescription": "Geben Sie den Namen des Projekts an.",
"setting.frontMatter.projects.items.properties.default.markdownDescription": "Geben Sie an, ob dieses Projekt das Standardprojekt zum Laden ist.",
"setting.frontMatter.sponsors.ai.enabled.markdownDescription": "Geben Sie an, ob Sie KI-Vorschläge aktivieren möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.sponsors.ai.enabled)",
"setting.frontMatter.extensibility.scripts.markdownDescription": "Geben Sie die Liste der Skripte an, die in Front Matter CMS geladen werden sollen. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.extensibility.scripts)",
"setting.frontMatter.experimental.markdownDescription": "Geben Sie an, ob Sie experimentelle Funktionen aktivieren möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.experimental)",
"setting.frontMatter.extends.markdownDescription": "Geben Sie die Liste der Pfade/URLs an, um die Front Matter CMS-Konfiguration zu erweitern. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.extends)",
"setting.frontMatter.content.autoUpdateDate.markdownDescription": "Geben Sie an, ob Sie das Änderungsdatum Ihres Artikels/seite automatisch aktualisieren möchten (nur für Inhalte im Inhaltsordner). [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.autoupdatedate)",
"setting.frontMatter.content.defaultFileType.markdownDescription": "Geben Sie den Standarddateityp für den zu erstellenden Inhalt an. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultfiletype)",
"setting.frontMatter.content.defaultSorting.markdownDescription": "Geben Sie die Standard-Sortierungsoption für das Inhaltsdashboard an. Sie können einen der Werte aus dem Enum verwenden oder Ihre eigene ID definieren. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultsorting)",
"setting.frontMatter.content.draftField.markdownDescription": "Definieren Sie das Entwurfsfeld, das Sie zum Verwalten Ihres Inhalts verwenden möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.draftfield)",
"setting.frontMatter.content.draftField.properties.type.description": "Typ des Entwurfsfelds, das Sie verwenden möchten",
"setting.frontMatter.content.draftField.properties.name.description": "Name des zu verwendenden Felds",
"setting.frontMatter.content.draftField.properties.invert.description": "Standardmäßig ist das Entwurfsfeld auf 'true' gesetzt, wenn der Inhalt ein Entwurf ist. Setzen Sie dies auf 'true', um es auf 'false' zu setzen.",
"setting.frontMatter.content.draftField.properties.choices.description": "Liste der Auswahlmöglichkeiten für das Feld",
"setting.frontMatter.content.fmHighlight.markdownDescription": "Geben Sie an, ob Sie das Front Matter in der Markdown-Datei hervorheben möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.fmhighlight)",
"setting.frontMatter.content.hideFm.markdownDescription": "Geben Sie an, ob Sie das Front Matter in der Markdown-Datei ausblenden möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefm)",
"setting.frontMatter.content.hideFmMessage.markdownDescription": "Geben Sie die Meldung an, die angezeigt werden soll, wenn das Front Matter ausgeblendet ist. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefmMessage)",
"setting.frontMatter.content.pageFolders.markdownDescription": "Dieses Array von Ordnern definiert, wo die Erweiterung Seiten abrufen oder erstellen kann. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.pagefolders)",
"setting.frontMatter.content.pageFolders.items.properties.title.description": "Name des Ordners",
"setting.frontMatter.content.pageFolders.items.properties.path.description": "Pfad des Ordners",
"setting.frontMatter.content.pageFolders.items.properties.excludeSubdir.description": "Unterordner ausschließen",
"setting.frontMatter.content.pageFolders.items.properties.previewPath.description": "Definiert einen benutzerdefinierten Vorschau-Pfad für den Ordner.",
"setting.frontMatter.content.pageFolders.items.properties.filePrefix.description": "Definiert ein Präfix für den Dateinamen.",
"setting.frontMatter.content.pageFolders.items.properties.contentTypes.description": "Definiert, welche Inhaltstypen für den aktuellen Speicherort verwendet werden können. Wenn nicht definiert, stehen alle Inhaltstypen zur Verfügung.",
"setting.frontMatter.content.placeholders.markdownDescription": "Dieses Array von Platzhaltern definiert die Platzhalter, die Sie in Ihren Inhaltstypen und Vorlagen verwenden können, um das Front Matter Ihres Inhalts automatisch zu befüllen. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.placeholders)",
"setting.frontMatter.content.placeholders.items.properties.id.description": "ID des Platzhalters, den Sie in Ihrem Inhaltstyp oder Ihrer Vorlage wie folgt verwenden: {{placeholder}}",
"setting.frontMatter.content.placeholders.items.properties.value.description": "Der Wert des Platzhalters",
"setting.frontMatter.content.placeholders.items.properties.script.description": "Das Skript, das ausgeführt wird, um den Wert des Platzhalters zu erhalten",
"setting.frontMatter.content.publicFolder.markdownDescription": "Geben Sie den Ordnernamen an, in dem sich alle Ihre Ressourcen befinden. Beispielsweise ist dies im Falle von Hugo der Ordner `static`. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.publicfolder)",
"setting.frontMatter.content.publicFolder.properties.path.description": "Geben Sie den Pfad des Assets-Ordners an.",
"setting.frontMatter.content.publicFolder.properties.relative.description": "Definiert, ob der Pfad zu Ihren Medien-Dateien relativ zur Inhaltsdatei sein soll.",
"setting.frontMatter.snippets.wrapper.enabled.markdownDescription": "Geben Sie an, ob Sie die Snippets umschließen möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontMatter.snippets.wrapper.enabled)",
"setting.frontMatter.content.snippets.markdownDescription": "Definieren Sie die Snippets, die Sie in Ihrem Inhalt verwenden möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.snippets)",
"setting.frontMatter.content.sorting.markdownDescription": "Definieren Sie die Sortieroptionen für Ihren Dashboard-Inhalt. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.sorting)",
"setting.frontMatter.content.sorting.items.properties.id.description": "Die ID der Sortierungsoption. Diese wird für das Speichern der zuletzt verwendeten Sortierungsoption oder der Standardoption verwendet.",
"setting.frontMatter.content.sorting.items.properties.title.description": "Name der Sortierbezeichnung",
"setting.frontMatter.content.sorting.items.properties.name.description": "Name des Metadatenfelds, nach dem sortiert werden soll",
"setting.frontMatter.content.sorting.items.properties.order.description": "Sortierreihenfolge",
"setting.frontMatter.content.sorting.items.properties.type.description": "Typ des Feldwerts",
"setting.frontMatter.content.supportedFileTypes.markdownDescription": "Geben Sie die Dateitypen an, die Sie in Front Matter verwenden möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.supportedfiletypes)",
"setting.frontMatter.content.wysiwyg.markdownDescription": "Gibt an, ob Sie die Markdown-Steuerelemente für What You See, Is What You Get (WYSIWYG) aktivieren/deaktivieren möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.content.wysiwyg)",
"setting.frontMatter.custom.scripts.markdownDescription": "Geben Sie den Pfad zu einem Node.js-Skript an, das ausgeführt werden soll. Der aktuelle Dateipfad wird als Argument bereitgestellt. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.custom.scripts)",
"setting.frontMatter.custom.scripts.items.properties.id.description": "ID des Skripts.",
"setting.frontMatter.custom.scripts.items.properties.title.description": "Titel, den Sie Ihrem Skript geben möchten. Wird als Titel der Schaltfläche angezeigt.",
"setting.frontMatter.custom.scripts.items.properties.script.description": "Pfad zum auszuführenden Skript",
"setting.frontMatter.custom.scripts.items.properties.nodeBin.description": "Pfad zum Node-Ausführbaren. Dies ist erforderlich, wenn NVM verwendet wird, um Verwirrung über die zu verwendende Node-Version zu vermeiden. (veraltet: stattdessen die Eigenschaft 'command' verwenden)",
"setting.frontMatter.custom.scripts.items.properties.bulk.description": "Das Skript für alle Inhaltsdateien ausführen",
"setting.frontMatter.custom.scripts.items.properties.output.description": "Definieren Sie, wo Sie Ihre Skriptausgabe anzeigen möchten. Standardmäßig handelt es sich um eine Benachrichtigung, aber Sie können angeben, dass sie in einem Editorfenster angezeigt wird.",
"setting.frontMatter.custom.scripts.items.properties.outputType.description": "Der Ausgabetyp für das Editorfenster. Kann beispielsweise auf 'markdown' geändert werden",
"setting.frontMatter.custom.scripts.items.properties.type.description": "Der Typ, für den das Skript verwendet wird.",
"setting.frontMatter.custom.scripts.items.properties.command.description": "Der Typ des auszuführenden Skripts.",
"setting.frontMatter.custom.scripts.items.properties.hidden.description": "Die Aktion in der Benutzeroberfläche ausblenden",
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.type.description": "Der Umgebungstyp, für den das Skript verwendet werden soll",
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.script.description": "Pfad zum auszuführenden Skript",
"setting.frontMatter.dashboard.content.pagination.markdownDescription": "Geben Sie an, ob Sie die Seitennummerierung für Ihren Inhalt aktivieren/deaktivieren möchten. Sie können Ihre Seitenzahl bis zu 52 definieren. Die Standardanzahl von Elementen pro Seite beträgt `16`. Die Deaktivierung der Seitennummerierung erfolgt durch Festlegung auf `false`. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.pagination)",
"setting.frontMatter.dashboard.content.cardTags.markdownDescription": "Geben Sie den Namen des Metadatenfelds an, das verwendet wird, um die Tags auf der Inhaltskarte anzuzeigen. Wenn leer oder null, werden die Tags auf der Karte ausgeblendet. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.cardtags)",
"setting.frontMatter.dashboard.content.card.fields.state.markdownDescription": "Geben Sie an, ob der Zustand/der Entwurfsstatus in der Ansicht der Inhaltskarte angezeigt werden soll. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.state)",
"setting.frontMatter.dashboard.content.card.fields.date.markdownDescription": "Geben Sie an, ob das Datum in der Ansicht der Inhaltskarte angezeigt werden soll. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.date)",
"setting.frontMatter.dashboard.content.card.fields.description.markdownDescription": "Geben Sie den Namen des Metadatenfelds an, das verwendet wird, um die Beschreibung auf der Inhaltskarte anzuzeigen. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.description)",
"setting.frontMatter.dashboard.content.card.fields.title.markdownDescription": "Geben Sie den Namen des Metadatenfelds an, das verwendet wird, um den Titel auf der Inhaltskarte anzuzeigen. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.title)",
"setting.frontMatter.dashboard.mediaSnippet.markdownDescription": "Geben Sie das Snippet für Ihre benutzerdefinierte Medieneinfügemarkierung an. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.mediasnippet)",
"setting.frontMatter.dashboard.mediaSnippet.items.description": "Verwenden Sie die Platzhalter `{mediaUrl}`, `{caption}`, `{alt}`, `{filename}`, `{mediaHeight}` und `{mediaWidth}` in Ihrem Snippet, um automatisch die Mediainformationen einzufügen.",
"setting.frontMatter.dashboard.openOnStart.markdownDescription": "Geben Sie an, ob das Dashboard beim Start von VS Code geöffnet werden soll. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.openonstart)",
"setting.frontMatter.data.files.markdownDescription": "Geben Sie die Datendateien an, die Sie für Ihre Website verwenden möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.data.files)",
"setting.frontMatter.data.files.items.properties.id.description": "Ihre eindeutige ID, die Sie für Ihre Datendatei verwenden möchten.",
"setting.frontMatter.data.files.items.properties.title.description": "Titel, den Sie Ihrer Datendatei geben möchten.",
"setting.frontMatter.data.files.items.properties.labelField.description": "Das Feld, das Sie als Bezeichnung für Ihre Dateneinträge verwenden möchten.",
"setting.frontMatter.data.files.items.properties.file.description": "Pfad zur zu ladenden Datei. Es werden nur JSON- oder YAML-Dateien unterstützt.",
"setting.frontMatter.data.files.items.properties.fileType.description": "Definiert, wie die Datei geparst werden soll. JSON ist der Standard.",
"setting.frontMatter.data.files.items.properties.schema.description": "Das JSON-Schema für Ihre Daten, das zur Darstellung des Datenformulars verwendet wird.",
"setting.frontMatter.data.files.items.properties.schema.properties.title.description": "Titel des Formulars.",
"setting.frontMatter.data.files.items.properties.schema.properties.type.description": "Definiert den Typ des Formulars. Standardmäßig 'object'.",
"setting.frontMatter.data.files.items.properties.schema.properties.required.description": "Definiert die erforderlichen Felder für das Formular.",
"setting.frontMatter.data.files.items.properties.schema.properties.properties.description": "Definiert die Felder des Formulars.",
"setting.frontMatter.data.files.items.properties.type.description": "Wenn Sie Datentypen verwenden, können Sie Ihre Typ-ID angeben.",
"setting.frontMatter.data.files.items.properties.singleEntry.description": "Wenn Sie eine einzelne Eingabe für Ihre Datendatei verwenden möchten.",
"setting.frontMatter.data.folders.markdownDescription": "Geben Sie die Datenspeicherorte an, die Sie für Ihre Website verwenden möchten. [Dokumentation prüfen](https://frontmatter.codes/docs/settings/overview#frontmatter.data.folders)",
"setting.frontMatter.data.folders.items.properties.id.description": "Ihre eindeutige ID, die Sie für Ihren Datenordner verwenden möchten.",
"setting.frontMatter.data.folders.items.properties.labelField.description": "Das Feld, das Sie als Bezeichnung für Ihre Dateneinträge verwenden möchten.",
"setting.frontMatter.data.folders.items.properties.path.description": "Pfad zum Ordner, um Dateien zu laden.",
"setting.frontMatter.data.folders.items.properties.type.description": "Wenn Sie Datentypen verwenden, können Sie Ihre Typ-ID angeben.",
"setting.frontMatter.data.folders.items.properties.singleEntry.description": "Wenn Sie für Ihre Daten Dateien im Ordner nur einen Eintrag verwenden möchten.",
"setting.frontMatter.data.types.markdownDescription": "Definieren Sie die Datentypen. Diese Typen können in Ihren Datendateien verwendet werden. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.data.types)",
"setting.frontMatter.data.types.items.properties.id.description": "Ihre eindeutige ID, die Sie für Ihren Datentyp verwenden möchten.",
"setting.frontMatter.file.preserveCasing.markdownDescription": "Gibt an, ob die Groß- und Kleinschreibung der Dateinamen aus dem Titel beibehalten werden soll. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.file.preservecasing)",
"setting.frontMatter.framework.id.markdownDescription": "Gibt die ID Ihres statischen Site-Generators oder Frameworks an, das Sie für Ihre Website verwenden. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.id)",
"setting.frontMatter.framework.startCommand.markdownDescription": "Gibt den Befehl an, den Sie zum Starten Ihres statischen Site-Generators oder Frameworks verwenden möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.startcommand)",
"setting.frontMatter.git.enabled.markdownDescription": "Gibt an, ob Sie die Git-Funktionen für Ihre Website verwenden möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.git.enabled)",
"setting.frontMatter.git.commitMessage.markdownDescription": "Gibt die Commit-Nachricht an, die Sie für die Synchronisierung verwenden möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.git.commitmessage)",
"setting.frontMatter.git.submodule.pull.markdownDescription": "Gibt an, ob Sie beim Synchronisieren Submodule aktualisieren möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.pull)",
"setting.frontMatter.git.submodule.push.markdownDescription": "Gibt an, ob Sie beim Synchronisieren Submodule pushen möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.push)",
"setting.frontMatter.git.submodule.branch.markdownDescription": "Gibt den Branch des Submoduls an, der ausgecheckt werden soll. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.branch)",
"setting.frontMatter.git.submodule.folder.markdownDescription": "Gibt den Submodulordner Ihrer Inhalte an. Dies kann nützlich sein, wenn Sie mehrere Submodule verwenden. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.folder)",
"setting.frontMatter.global.activeMode.markdownDescription": "Gibt den aktivierten Modus für Front Matter an. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.global.activemode)",
"setting.frontMatter.global.modes.markdownDescription": "Definieren Sie die Modi, die Sie für Front Matter verwenden möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.global.modes)",
"setting.frontMatter.global.modes.items.properties.id.description": "Die ID Ihres Modus.",
"setting.frontMatter.global.modes.items.properties.features.description": "Die Funktionen, die Sie für Ihren Modus verwenden möchten.",
"setting.frontMatter.global.notifications.markdownDescription": "Legt fest, welche Benachrichtigungen angezeigt werden sollen. Standardmäßig werden alle Benachrichtigungstypen angezeigt. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.global.notifications)",
"setting.frontMatter.global.disabledNotifications.markdownDescription": "Dies ist ein Array mit den Benachrichtigungstypen, die für Front Matter CMS deaktiviert werden können. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.global.disablednotifications)",
"setting.frontMatter.media.defaultSorting.markdownDescription": "Gibt die Standard-Sortieroption für das Medien-Dashboard an. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.media.defaultsorting)",
"setting.frontMatter.media.supportedMimeTypes.markdownDescription": "Gibt die MIME-Typen an, die für die Mediadateien unterstützt werden sollen. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.media.supportedmimetypes)",
"setting.frontMatter.panel.freeform.markdownDescription": "Gibt an, ob Sie sich selbst das Eingeben unbekannter Tags/Kategorien im Tag-Picker ermöglichen möchten (wenn aktiviert, haben Sie anschließend die Möglichkeit, sie zu speichern). Standard: true. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.freeform)",
"setting.frontMatter.preview.host.markdownDescription": "Gibt die Host-URL (Beispiel: http://localhost:1313) an, die beim Öffnen der Vorschau verwendet werden soll. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.host)",
"setting.frontMatter.preview.pathName.markdownDescription": "Gibt den Pfad an, den Sie nach dem Host und vor Ihrem Slug hinzufügen möchten. Dies kann zum Beispiel verwendet werden, um das Jahr/Monat wie z. B. `yyyy/MM` einzuschließen. Das Datum wird basierend auf dem Wert des Datumsfelds des Artikels generiert. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.pathname)",
"setting.frontMatter.site.baseURL.markdownDescription": "Gibt die Basis-URL Ihrer Website an, die für SEO-Überprüfungen verwendet wird. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.site.baseurl)",
"setting.frontMatter.taxonomy.alignFilename.markdownDescription": "Richtet den Dateinamen mit dem neuen Slug aus, wenn dieser generiert wird. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.alignfilename)",
"setting.frontMatter.taxonomy.categories.markdownDescription": "Gibt die Kategorien an, die in der Front Matter verwendet werden können. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.categories)",
"setting.frontMatter.taxonomy.commaSeparatedFields.markdownDescription": "Gibt die Feldnamen an, die von Front Matter als kommaseparierte Arrays behandelt werden sollen. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.commaseparatedfields)",
"setting.frontMatter.taxonomy.commaSeparatedFields.items.description": "Name der Felder, die Sie als kommaseparierte Arrays verwenden möchten.",
"setting.frontMatter.taxonomy.contentTypes.markdownDescription": "Gibt den Typ der Inhalte an, die Sie für Ihre Artikel/Seiten/etc. verwenden möchten. Stellen Sie sicher, dass der `type` in Ihrer Front Matter korrekt gesetzt ist. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.contenttypes)",
"setting.frontMatter.taxonomy.contentTypes.items.description": "Definieren Sie die Content-Typen, die Sie in Front Matter verwenden möchten.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.name.description": "Definiert den Typ des Feldes",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fileType.description": "Gibt den Typ des Inhalts an, den Sie erstellen möchten.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.description": "Definiert die Felder des Content-Typs",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.description": "Definieren Sie die Content-Typen, die Sie in Front Matter verwenden möchten.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.type.description": "Definiert den Typ des Feldes",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.name.description": "Name des zu verwendenden Feldes",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.title.description": "Titel, der in der Benutzeroberfläche angezeigt werden soll",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.description.description": "Beschreibung, die in der Benutzeroberfläche angezeigt werden soll",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.default.description": "Standardwert",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.description": "Definieren Sie Ihre Auswahlmöglichkeiten",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.id.description": "Die Auswahl-ID",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.title.description": "Der Auswahl-Titel",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.single.description": "Ist ein Einzelzeilenfeld",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.wysiwyg.description": "Ist ein WYSIWYG-Feld (HTML-Ausgabe)",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.multiple.description": "Erlauben Sie die Auswahl mehrerer Werte?",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isPreviewImage.description": "Gibt an, ob das Bildfeld als Vorschau verwendet werden kann. Beachten Sie, dass pro Content-Typ nur ein Vorschau-Bild möglich ist.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.hidden.description": "Möchten Sie das Feld im Metadaten-Bereich verbergen?",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyId.description": "Die ID Ihres Taxonomiefeldes. Es darf nicht den Wert \"tags\" oder \"categories\" enthalten.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.fileExtensions.description": "Gibt die Dateierweiterungen an, die für den Dateipicker zugelassen sind",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.fieldGroup.description": "Die ID(s) Ihrer Feldgruppe(n), die in der Einstellung `frontMatter.taxonomy.fieldGroups` definiert sind",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataType.description": "Die ID(s) Ihrer Datentyp(en), die in der Einstellung `frontMatter.data.types` definiert sind",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.description": "Gibt die Optionen für das Zahlenfeld an",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.isDecimal.description": "Gibt an, ob die Zahl eine Dezimalzahl ist",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.min.description": "Der Mindestwert",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.max.description": "Der Maximalwert",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.step.description": "Der Schrittwert",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyLimit.description": "Begrenzen Sie die Anzahl der auszuwählenden Taxonomien. Setzen Sie den Wert auf 0, um unbegrenzt zuzulassen.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isPublishDate.description": "Gibt an, ob das Feld das Feld für das Veröffentlichungsdatum ist",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isModifiedDate.description": "Gibt an, ob das Feld das Feld für das Änderungsdatum ist",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileId.description": "Gibt die ID der Datendatei an, die für dieses Feld verwendet werden soll",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileKey.description": "Gibt den Schlüssel der Datendatei an, die für dieses Feld verwendet werden soll",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileValue.description": "Gibt den Eigenschaftsnamen an, der verwendet wird, um den Wert für das Feld anzuzeigen",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.editable.description": "Gibt an, ob das Feld bearbeitbar ist",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.encodeEmoji.description": "Gibt an, ob das Feld Emojis kodieren soll",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dateFormat.description": "Gibt das Datumsformat an, das verwendet werden soll.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.required.description": "Gibt an, ob das Feld erforderlich ist.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeName.description": "Gibt den Namen des Content-Typs an, um Inhalte für das contentRelationship-Feld zu filtern.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeValue.description": "Gibt den Wert an, der für das contentRelationship-Feld eingefügt werden soll.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.description": "Gibt die Bedingungen an, unter denen das Feld angezeigt werden soll.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.fieldRef.description": "Die Feld-ID, die verwendet werden soll.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.operator.description": "Der Operator, der verwendet werden soll.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.value.description": "Der Wert, mit dem verglichen werden soll.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.caseSensitive.description": "Gibt an, ob der Vergleich eine Groß-/Kleinschreibung beachtet. Standard: true.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.pageBundle.description": "Gibt an, ob beim Erstellen neuer Inhalte ein Ordner erstellt werden soll.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.previewPath.description": "Definiert einen benutzerdefinierten Vorschau-Pfad für den Content-Typ.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.template.description": "Eine optionale Vorlage, die zum Erstellen neuer Inhalte verwendet werden kann.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.postScript.description": "Ein optionaler Post-Skript, der nach der Erstellung neuer Inhalte verwendet werden kann.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.filePrefix.description": "Definiert ein Präfix für den Dateinamen.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.defaultFileName.description": "Standard-Dateiname, der beim Erstellen neuer Inhalte verwendet werden soll.",
"setting.frontMatter.taxonomy.customTaxonomy.markdownDescription": "Gibt die Daten für das benutzerdefinierte Taxonomiefeld an. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.id.description": "ID für Ihr Taxonomiefeld. Es darf nicht den Wert \"tags\" oder \"categories\" enthalten.",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.options.description": "Optionen, aus denen Sie auswählen können.",
"setting.frontMatter.taxonomy.dateField.markdownDescription": "Diese Einstellung wird verwendet, um das Veröffentlichungsdatum-Feld Ihrer Artikel zu definieren. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.datefield)",
"setting.frontMatter.taxonomy.dateFormat.markdownDescription": "Gibt das Datumsformat für Ihre Artikel an. Weitere Informationen finden Sie unter [date-fns formatierung](https://date-fns.org/v2.0.1/docs/format). [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.dateformat)",
"setting.frontMatter.taxonomy.fieldGroups.markdownDescription": "Definiert die Feldgruppen, die Sie für Ihre Blockfelder verwenden möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.fieldgroups)",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.id.description": "Der Name der Feldgruppe",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.labelField.description": "Der Name des Feldes, das als Anzeigewert verwendet werden soll",
"setting.frontMatter.taxonomy.frontMatterType.markdownDescription": "Gibt den Typ von Front Matter an, der verwendet werden soll. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.frontmattertype)",
"setting.frontMatter.taxonomy.indentArrays.markdownDescription": "Gibt an, ob Arrays in der Front Matter eingerückt werden sollen. Standard: true. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.indentarrays)",
"setting.frontMatter.taxonomy.modifiedField.markdownDescription": "Diese Einstellung wird verwendet, um das Änderungsdatum-Feld Ihrer Artikel zu definieren. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.modifiedfield)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.markdownDescription": "Gibt die Eigenschaften an, bei denen Anführungszeichen entfernt werden sollen. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.nopropertyvaluequotes)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.items.description": "Name der Eigenschaften, von denen Sie Anführungszeichen entfernen möchten.",
"setting.frontMatter.taxonomy.seoContentLengh.markdownDescription": "Gibt die optimale Mindestlänge für Ihre Artikel an. Zwischen 1.760 Wörtern 2.400 ist die absolut ideale Artikelänge für SEO im Jahr 2021. (auf `-1` setzen, um es auszuschalten). [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seocontentlengh)",
"setting.frontMatter.taxonomy.seoDescriptionField.markdownDescription": "Gibt den Namen des SEO-Beschreibungsfeldes für Ihre Seite an. Standard ist 'description'. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionfield)",
"setting.frontMatter.taxonomy.seoDescriptionLength.markdownDescription": "Gibt die optimale Beschreibungslänge für SEO an (auf `-1` setzen, um es auszuschalten). [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionlength)",
"setting.frontMatter.taxonomy.seoSlugLength.markdownDescription": "Gibt die optimale Schlagwortlänge für SEO an (auf `-1` setzen, um es auszuschalten). [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seosluglength)",
"setting.frontMatter.taxonomy.seoTitleField.markdownDescription": "Gibt den Namen des SEO-Titelfelds für Ihre Seite an. Standard ist 'title'. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlefield)",
"setting.frontMatter.taxonomy.seoTitleLength.markdownDescription": "Gibt die optimale Titellänge für SEO an (auf `-1` setzen, um es auszuschalten). [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlelength)",
"setting.frontMatter.taxonomy.slugPrefix.markdownDescription": "Gibt ein Präfix für den Schlagwort an. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugprefix)",
"setting.frontMatter.taxonomy.slugSuffix.markdownDescription": "Gibt ein Suffix für den Schlagwort an. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugsuffix)",
"setting.frontMatter.taxonomy.tags.markdownDescription": "Gibt die Schlagwörter an, die in der Front Matter verwendet werden können. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.telemetry.disable.markdownDescription": "Gibt an, ob die Telemetrie deaktiviert werden soll. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.telemetry.disable)",
"setting.frontMatter.templates.enabled.markdownDescription": "Gibt an, ob Vorlagen verwendet werden sollen. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.enabled)",
"setting.frontMatter.templates.folder.markdownDescription": "Gibt den Ordner an, der für Ihre Artikelvorlagen verwendet werden soll. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.folder)",
"setting.frontMatter.templates.prefix.markdownDescription": "Gibt das Präfix an, das Sie für die Dateinamen Ihrer neuen Artikel hinzufügen möchten. [Weitere Informationen in der Dokumentation](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.prefix)",
"setting.frontMatter.dashboard.mediaSnippet.deprecationMessage": "Diese Einstellung ist veraltet und wird in der nächsten Hauptversion entfernt. Bitte definieren Sie Ihr Medien-Snippet in der `frontMatter.content.snippet` Einstellung.",
"setting.frontMatter.taxonomy.dateField.deprecationMessage": "Diese Einstellung ist veraltet und wird in der nächsten Hauptversion entfernt. Bitte verwenden Sie stattdessen die neuen `isPublishDate`-Einstellungen in den Datumsfeldern Ihrer Content-Typen.",
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "Diese Einstellung ist veraltet und wird in der nächsten Hauptversion entfernt. Bitte verwenden Sie stattdessen die neuen `isModifiedDate`-Einstellungen in den Datumsfeldern Ihrer Content-Typen.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "🚧: Specify the name of the custom field type to use."
}

244
package.nls.ja.json Normal file
View File

@@ -0,0 +1,244 @@
{
"command.frontMatter.project.switch": "プロジェクトの切り替え",
"command.frontMatter.config.reload": "構成を再読み込み",
"command.frontMatter.authenticate": "認証",
"command.frontMatter.contenttype.generate": "表示中のファイルをもとに記事タイプを作成",
"command.frontMatter.contenttype.addMissingFields": "この記事タイプの設定にないフィールドをfront matterから追加",
"command.frontMatter.contenttype.setContentType": "表示中のファイルに記事タイプを設定",
"command.frontMatter.markup.blockquote": "引用",
"command.frontMatter.markup.bold": "太字",
"command.frontMatter.dashboard.close": "ダッシュボードを閉じる",
"command.frontMatter.markup.code": "コード",
"command.frontMatter.markup.codeblock": "コードブロック",
"command.frontMatter.markup.hyperlink": "ハイパーリンク",
"command.frontMatter.collapseSections": "メニューを折りたたむ",
"command.frontMatter.initTemplate": "テンプレートフォルダーを初期化",
"command.frontMatter.createTemplate": "現在のファイルからテンプレートを作成",
"command.frontMatter.createCategory": "新規カテゴリーを追加",
"command.frontMatter.createContent": "記事タイプまたはテンプレートから新しい記事を作成",
"command.frontMatter.createTag": "新規タグを作成",
"command.frontMatter.diagnostics": "診断ログ",
"command.frontMatter.exportTaxonomy": "全てのタグとカテゴリーを設定にエクスポート",
"command.frontMatter.createFromTemplate": "新しい記事をテンプレートから作成",
"command.frontMatter.registerFolder": "フォルダーを登録",
"command.frontMatter.unregisterFolder": "フォルダーの登録を解除",
"command.frontMatter.generateSlug": "記事タイトルからスラッグを生成",
"command.frontMatter.markup.heading": "見出し",
"command.frontMatter.init": "プロジェクトの初期設定",
"command.frontMatter.insertCategories": "カテゴリーを追加",
"command.frontMatter.insertMedia": "メディアを挿入",
"command.frontMatter.insertSnippet": "スニペットを挿入",
"command.frontMatter.insertTags": "タグを追加",
"command.frontMatter.markup.italic": "イタリック",
"command.frontMatter.dashboard": "ダッシュボードを開く",
"command.frontMatter.dashboard.data": "データのダッシュボードを開く",
"command.frontMatter.dashboard.media": "メディアのダッシュボードを開く",
"command.frontMatter.dashboard.snippets": "スニペットのダッシュボードを開く",
"command.frontMatter.dashboard.taxonomy": "タクソノミーのダッシュボードを開く",
"command.frontMatter.markup.orderedlist": "順序付きリスト",
"command.frontMatter.markup.options": "他のマークアップオプション",
"command.frontMatter.preview": "記事のプレビューを開く",
"command.frontMatter.chatbot": "Front Matter AIに質問する",
"command.frontMatter.promoteSettings": "ローカル設定をチームレベルへ昇格させる",
"command.frontMatter.remap": "全ての記事のタグまたはカテゴリーを再配置または削除する",
"command.frontMatter.setLastModifiedDate": "最終更新日を設定する",
"command.frontMatter.markup.strikethrough": "取り消し線",
"command.frontMatter.mode.switch": "モードの切り替え",
"command.frontMatter.markup.tasklist": "タスクリスト",
"command.frontMatter.markup.unorderedlist": "順序なしリスト",
"command.frontMatter.git.sync": "同期",
"command.frontMatter.cache.clear": "キャッシュをクリア",
"settings.configuration.title": "Front Matter: チームで作業する場合はfrontmatter.jsonで設定してください。",
"setting.frontMatter.projects.markdownDescription": "Front Matter CMSを利用するプロジェクトを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.projects)",
"setting.frontMatter.projects.items.properties.name.markdownDescription": "🚧: Specify the name of the project.",
"setting.frontMatter.projects.items.properties.default.markdownDescription": "🚧: Specify if this project is the default project to load.",
"setting.frontMatter.sponsors.ai.enabled.markdownDescription": "AIによる提案を利用します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.sponsors.ai.enabled)",
"setting.frontMatter.extensibility.scripts.markdownDescription": "Front Matter CMSで読み込むスクリプトのリストを指定します。. [ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.extensibility.scripts)",
"setting.frontMatter.experimental.markdownDescription": "実験的な機能をオンにします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.experimental)",
"setting.frontMatter.extends.markdownDescription": "Front Matter CMSの構成を拡張するパス/URLのリストを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.extends)",
"setting.frontMatter.content.autoUpdateDate.markdownDescription": "記事やページの最終編集日を自動で更新します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.autoupdatedate)",
"setting.frontMatter.content.defaultFileType.markdownDescription": "新しい記事を作成する際の既定のファイル形式を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultfiletype)",
"setting.frontMatter.content.defaultSorting.markdownDescription": "ダッシュボード上に表示される記事一覧の既定の並び順を設定します。Enum列挙型や任意のIDを指定してください。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultsorting)",
"setting.frontMatter.content.draftField.markdownDescription": "記事の下書きステータスを管理するフィールドを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.draftfield)",
"setting.frontMatter.content.draftField.properties.type.description": "🚧: Type of the draft field you want to use",
"setting.frontMatter.content.draftField.properties.name.description": "🚧: Name of the field to use",
"setting.frontMatter.content.draftField.properties.invert.description": "🚧: By default the draft field is set to true when the content is a draft. Set this to true to set it to false.",
"setting.frontMatter.content.draftField.properties.choices.description": "🚧: List of choices for the field",
"setting.frontMatter.content.fmHighlight.markdownDescription": "Markdownファイル内のfront matterをハイライトします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.fmhighlight)",
"setting.frontMatter.content.hideFm.markdownDescription": "Markdownファイル内のfront matterを非表示にします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefm)",
"setting.frontMatter.content.hideFmMessage.markdownDescription": "front matterが非表示の際に、編集画面に表示するメッセージを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefmmessage)",
"setting.frontMatter.content.pageFolders.markdownDescription": "フォルダーを配列で定義して、この拡張機能が記事を取得したり新しい記事を作成できるようにします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.pagefolders)",
"setting.frontMatter.content.pageFolders.items.properties.title.description": "🚧: Name of the folder",
"setting.frontMatter.content.pageFolders.items.properties.path.description": "🚧: Path of the folder",
"setting.frontMatter.content.pageFolders.items.properties.excludeSubdir.description": "🚧: Exclude sub-directories",
"setting.frontMatter.content.pageFolders.items.properties.previewPath.description": "🚧: Defines a custom preview path for the folder.",
"setting.frontMatter.content.pageFolders.items.properties.filePrefix.description": "🚧: Defines a prefix for the file name.",
"setting.frontMatter.content.pageFolders.items.properties.contentTypes.description": "🚧: Defines which content types can be used for the current location. If not defined, all content types will be available.",
"setting.frontMatter.content.placeholders.markdownDescription": "記事タイプとテンプレートで使用するプレースホルダーを配列で定義して、記事のfront matterを自動で入力できるようにします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.placeholders)",
"setting.frontMatter.content.placeholders.items.properties.id.description": "🚧: ID of the placeholder, in your content type or template, use it as follows: {{placeholder}}",
"setting.frontMatter.content.placeholders.items.properties.value.description": "🚧: The placeholder its value",
"setting.frontMatter.content.placeholders.items.properties.script.description": "🚧: The script to execute to get the value of the placeholder",
"setting.frontMatter.content.publicFolder.markdownDescription": "アセットが保存されているフォルダーを設定します。例えば、Hugoでは`static`フォルダーです。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.publicfolder)",
"setting.frontMatter.content.publicFolder.properties.path.description": "アセットフォルダーのパスを指定します。",
"setting.frontMatter.content.publicFolder.properties.relative.description": "メディアファイルへのパスがコンテンツファイルに対して相対的であるかを定義します。",
"setting.frontMatter.snippets.wrapper.enabled.markdownDescription": "スニペット挿入時にコメントでラップします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontMatter.snippets.wrapper.enabled)",
"setting.frontMatter.content.snippets.markdownDescription": "記事中に使用するスニペットを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.snippets)",
"setting.frontMatter.content.sorting.markdownDescription": "ダッシュボード上での記事の並べ替えオプションを追加します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.sorting)",
"setting.frontMatter.content.sorting.items.properties.id.description": "🚧: The ID of the sorting option. This will be used for the storing the last used sorting option or the default option.",
"setting.frontMatter.content.sorting.items.properties.title.description": "🚧: Name of the sorting label",
"setting.frontMatter.content.sorting.items.properties.name.description": "🚧: Name of the metadata field to sort by",
"setting.frontMatter.content.sorting.items.properties.order.description": "🚧: Order of the sorting",
"setting.frontMatter.content.sorting.items.properties.type.description": "🚧: Type of the field value",
"setting.frontMatter.content.supportedFileTypes.markdownDescription": "Front Matterでサポートされるファイル形式を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.supportedfiletypes)",
"setting.frontMatter.content.wysiwyg.markdownDescription": "What You See, Is What You GetWYSIWYGMarkdownコントロールを有効にします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.wysiwyg)",
"setting.frontMatter.custom.scripts.markdownDescription": "実行するNode.jsスクリプトのパスを指定します。現在のファイルのパスが引数として渡されます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.custom.scripts)",
"setting.frontMatter.custom.scripts.items.properties.id.description": "🚧: ID of the script.",
"setting.frontMatter.custom.scripts.items.properties.title.description": "🚧: Title you want to give to your script. Will be shown as the title of the button.",
"setting.frontMatter.custom.scripts.items.properties.script.description": "🚧: Path to the script to execute",
"setting.frontMatter.custom.scripts.items.properties.nodeBin.description": "🚧: Path to the node executable. This is required when using NVM, so that there is no confusion of which node version to use. (deprecated: use the command property instead)",
"setting.frontMatter.custom.scripts.items.properties.bulk.description": "🚧: Run the script for all content files",
"setting.frontMatter.custom.scripts.items.properties.output.description": "🚧: Define where you want to output your script output. Default is a notification, but you can specify to show it in an editor panel.",
"setting.frontMatter.custom.scripts.items.properties.outputType.description": "🚧: The type of output for the editor panel. Can be used to change it to 'markdown' for example",
"setting.frontMatter.custom.scripts.items.properties.type.description": "🚧: The type for which the script will be used.",
"setting.frontMatter.custom.scripts.items.properties.command.description": "🚧: The type of script you want to execute.",
"setting.frontMatter.custom.scripts.items.properties.hidden.description": "🚧: Hide the action from the UI",
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.type.description": "🚧: The environment type for which the script needs to be used",
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.script.description": "🚧: Path to the script to execute",
"setting.frontMatter.dashboard.content.pagination.markdownDescription": "ページネーションの有効/無効を設定します。ページ数は最大52まで設定できます。規定値は`16`です。ページ分割を無効にするには`false`を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.pagination)",
"setting.frontMatter.dashboard.content.cardTags.markdownDescription": "記事一覧をカード型で表示する際、どのメタデータフィールドをタグとして使うかを指定します。空欄またはnull値の場合、タグは表示されなくなります。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.cardtags)",
"setting.frontMatter.dashboard.content.card.fields.state.markdownDescription": "記事一覧をカード型で表示する際、下書き・公開済みのステータスを表示します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.state)",
"setting.frontMatter.dashboard.content.card.fields.date.markdownDescription": "記事一覧をカード型で表示する際、日付を表示します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.date)",
"setting.frontMatter.dashboard.content.card.fields.description.markdownDescription": "記事一覧をカード型で表示する際、どのメタデータフィールドをディスクリプションとして使うかを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.description)",
"setting.frontMatter.dashboard.content.card.fields.title.markdownDescription": "記事一覧をカード型で表示する際、どのメタデータフィールドをタイトルとして使うかを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.title)",
"setting.frontMatter.dashboard.mediaSnippet.markdownDescription": "🚧: Specify the a snippet for your custom media insert markup. [ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.mediasnippet)",
"setting.frontMatter.dashboard.mediaSnippet.items.description": "スニペット内で `{mediaUrl}`, `{caption}`, `{alt}`, `{filename}`, `{mediaHeight}`, `{mediaWidth}` のプレースホルダーを使用して、メディア情報を自動的に挿入します。",
"setting.frontMatter.dashboard.openOnStart.markdownDescription": "VS Codeの起動時にダッシュボードを表示します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.openonstart)",
"setting.frontMatter.data.files.markdownDescription": "ウェブサイトに使用するデータのファイルを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.data.files)",
"setting.frontMatter.data.files.items.properties.id.description": "🚧: Your unique ID you want to use for your data file.",
"setting.frontMatter.data.files.items.properties.title.description": "🚧: Title you want to give to your data file.",
"setting.frontMatter.data.files.items.properties.labelField.description": "🚧: The field you want to use as label for your data entries.",
"setting.frontMatter.data.files.items.properties.file.description": "🚧: Path to the file to load. Only JSON or YAML files are supported.",
"setting.frontMatter.data.files.items.properties.fileType.description": "🚧: Defines how you want to parse the file. JSON is the default.",
"setting.frontMatter.data.files.items.properties.schema.description": "🚧: The JSON schema for your data which will be used to render the data form.",
"setting.frontMatter.data.files.items.properties.schema.properties.title.description": "🚧: Title of the form.",
"setting.frontMatter.data.files.items.properties.schema.properties.type.description": "🚧: Defines the type of the form. Default is 'object'.",
"setting.frontMatter.data.files.items.properties.schema.properties.required.description": "🚧: Defines the required fields for the form.",
"setting.frontMatter.data.files.items.properties.schema.properties.properties.description": "🚧: Defines the fields of the form.",
"setting.frontMatter.data.files.items.properties.type.description": "🚧: If you are using data types, you can specify your type ID.",
"setting.frontMatter.data.files.items.properties.singleEntry.description": "🚧: If you want to use a single entry for your data file.",
"setting.frontMatter.data.folders.markdownDescription": "ウェブサイトに使用するデータのフォルダーを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.data.folders)",
"setting.frontMatter.data.folders.items.properties.id.description": "🚧: Your unique ID you want to use for your data folder.",
"setting.frontMatter.data.folders.items.properties.labelField.description": "🚧: The field you want to use as label for your data entries.",
"setting.frontMatter.data.folders.items.properties.path.description": "🚧: Path to the folder to load files.",
"setting.frontMatter.data.folders.items.properties.type.description": "🚧: If you are using data types, you can specify your type ID.",
"setting.frontMatter.data.folders.items.properties.singleEntry.description": "🚧: If you want to use a single entry for your data files in the folder.",
"setting.frontMatter.data.types.markdownDescription": "データタイプを指定します。これらのタイプは、データファイルで使用できます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.data.types)",
"setting.frontMatter.data.types.items.properties.id.description": "🚧: Your unique ID you want to use for your data type.",
"setting.frontMatter.file.preserveCasing.markdownDescription": "タイトルからファイル名の大文字と小文字を区別します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.file.preservecasing)",
"setting.frontMatter.framework.id.markdownDescription": "ウェブサイトに使用している静的サイトジェネレーターまたはフレームワークのIDを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.id)",
"setting.frontMatter.framework.startCommand.markdownDescription": "静的サイト・ジェネレーターまたはフレームワークを起動させるコマンドを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.startcommand)",
"setting.frontMatter.git.enabled.markdownDescription": "ウェブサイトにGit Actionsを使用するかどうかを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.git.enabled)",
"setting.frontMatter.git.commitMessage.markdownDescription": "同期に使用するコミットメッセージを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.git.commitmessage)",
"setting.frontMatter.git.submodule.pull.markdownDescription": "同期の際にサブモジュールをpullするかどうかを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.pull)",
"setting.frontMatter.git.submodule.push.markdownDescription": "同期の際にサブモジュールをpushするかどうかを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.push)",
"setting.frontMatter.git.submodule.branch.markdownDescription": "チェックアウトするサブモジュールのブランチを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.branch)",
"setting.frontMatter.git.submodule.folder.markdownDescription": "コンテンツのサブモジュールフォルダーを指定します。複数のサブモジュールを使用する場合に便利です。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.folder)",
"setting.frontMatter.global.activeMode.markdownDescription": "Front Matterで有効なモードを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.global.activemode)",
"setting.frontMatter.global.modes.markdownDescription": "Front Matterで利用するモードを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.global.modes)",
"setting.frontMatter.global.modes.items.properties.id.description": "🚧: The ID of your mode.",
"setting.frontMatter.global.modes.items.properties.features.description": "🚧: The features you want to use for your mode.",
"setting.frontMatter.global.notifications.markdownDescription": "表示したい通知を設定します。既定では全ての通知が表示されます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.global.notifications)",
"setting.frontMatter.global.disabledNotificaitons.markdownDescription": "表示しない通知を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.global.disablednotifications)",
"setting.frontMatter.media.defaultSorting.markdownDescription": "ダッシュボードのメディア一覧での既定の並び順を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.media.defaultsorting)",
"setting.frontMatter.media.supportedMimeTypes.markdownDescription": "メディアファイルでサポートされるMIMEタイプを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.media.supportedmimetypes)",
"setting.frontMatter.panel.freeform.markdownDescription": "未登録のタグ/カテゴリーをタグピッカーに入力することを許可するかどうかを設定します有効にすると、後で保存するオプションが使えます。規定値はtrue。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.freeform)",
"setting.frontMatter.preview.host.markdownDescription": "プレビュー表示に使用するホストのURLを設定します`http://localhost:1313`)。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.host)",
"setting.frontMatter.preview.pathName.markdownDescription": "ホストパスとスラッグの間に追加したいパスを設定します。例えば、パスに`yyyy/MM`などの日付を含めたい場合等に使えます。日付は記事の日付フィールドの値に基づいて生成されます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.pathname)",
"setting.frontMatter.site.baseURL.markdownDescription": "ベースURLを設定します。これはSEOチェックに利用されます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.site.baseurl)",
"setting.frontMatter.taxonomy.alignFilename.markdownDescription": "ファイル生成時にファイル名をスラッグに合わせる[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.alignfilename)",
"setting.frontMatter.taxonomy.categories.markdownDescription": "Front Matterで利用するカテゴリーを管理します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.categories)",
"setting.frontMatter.taxonomy.commaSeparatedFields.markdownDescription": "カンマ区切りで配列を管理するフィールド名を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.commaseparatedfields)",
"setting.frontMatter.taxonomy.commaSeparatedFields.items.description": "コンマ区切りの配列として使用するフィールドの名前。",
"setting.frontMatter.taxonomy.contentTypes.markdownDescription": "記事・ページ・その他で利用したい記事タイプを設定します。front matterで正しく`type`が設定されていることを確認してください。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.contenttypes)",
"setting.frontMatter.taxonomy.contentTypes.items.description": "Front Matterで使用するコンテンツタイプを定義します。",
"setting.frontMatter.taxonomy.contentTypes.items.properties.name.description": "🚧: Define the type of field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fileType.description": "🚧: Specifies the type of content you want to create.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.description": "🚧: Define the fields of the content type",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.description": "Front Matterで使用するコンテンツタイプを定義します。",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.type.description": "🚧: Define the type of field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.name.description": "🚧: Name of the field to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.title.description": "🚧: Title to show in the UI",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.description.description": "🚧: Description to show in the UI",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.default.description": "🚧: Default value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.description": "🚧: Define your choices",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.id.description": "🚧: The choice ID",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.title.description": "🚧: The choice title",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.single.description": "🚧: Is a single line field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.wysiwyg.description": "🚧: Is a WYSIWYG field (HTML output)",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.multiple.description": "🚧: Do you allow to select multiple values?",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isPreviewImage.description": "🚧: Specify if the image field can be used as preview. Be aware, you can only have one preview image per content type.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.hidden.description": "🚧: Do you want to hide the field from the metadata section?",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyId.description": "🚧: The ID of your taxonomy field. It cannot contain the \"tags\" or \"categories\" value.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.fileExtensions.description": "🚧: Specify the file extensions to allow for the file picker",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.fieldGroup.description": "🚧: The ID(s) of your field group(s) defined in the `frontMatter.taxonomy.fieldGroups` setting",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataType.description": "🚧: The ID(s) of your data type(s) defined in the `frontMatter.data.types` setting",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.description": "🚧: Specify the options for the number field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.isDecimal.description": "🚧: Specify if the number is a decimal",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.min.description": "🚧: The minimum value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.max.description": "🚧: The maximum value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.step.description": "🚧: The step value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyLimit.description": "🚧: Limit the number of taxonomies to select. Set to 0 to allow unlimited.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isPublishDate.description": "🚧: Specify if the field is the publish date field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isModifiedDate.description": "🚧: Specify if the field is the modified date field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileId.description": "🚧: Specify the ID of the data file to use for this field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileKey.description": "🚧: Specify the key of the data file to use for this field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileValue.description": "🚧: Specify the property name that will be used to show the value for the field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.editable.description": "🚧: Specify if the field is editable",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.encodeEmoji.description": "🚧: Specify if the field should encode emoji",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dateFormat.description": "🚧: Specify the date format to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.required.description": "🚧: Specify if the field is required",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeName.description": "🚧: Specify the content type name to filter content for the contentRelationship field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeValue.description": "🚧: Specify the value to insert for the contentRelationship field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.description": "🚧: Specify the conditions to show the field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.fieldRef.description": "🚧: The field ID to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.operator.description": "🚧: The operator to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.value.description": "🚧: The value to compare",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.caseSensitive.description": "🚧: Specify if the comparison is case sensitive. Default: true",
"setting.frontMatter.taxonomy.contentTypes.items.properties.pageBundle.description": "🚧: Specify if you want to create a folder when creating new content.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.previewPath.description": "🚧: Defines a custom preview path for the content type.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.template.description": "🚧: An optional template that can be used for creating new content.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.postScript.description": "🚧: An optional post script that can be used after new content creation.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.filePrefix.description": "🚧: Defines a prefix for the file name.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.defaultFileName.description": "🚧: Default file name to use when creating new content.",
"setting.frontMatter.taxonomy.customTaxonomy.markdownDescription": "カスタムタクソノミーのフィールドデータを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.id.description": "🚧: ID for your taxonomy field. It cannot contain the \"tags\" or \"categories\" value.",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.options.description": "🚧: Options from which you can pick.",
"setting.frontMatter.taxonomy.dateField.markdownDescription": "🚧: This setting is used to define the publishing date field of your articles. [ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.datefield)",
"setting.frontMatter.taxonomy.dateFormat.markdownDescription": "記事の日付フォーマットを指定します。詳しくは[date-fns formatting](https://date-fns.org/v2.0.1/docs/format)を確認してください。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.dateformat)",
"setting.frontMatter.taxonomy.fieldGroups.markdownDescription": "ブロックフィールドで使用したいフィールドグループを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.fieldgroups)",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.id.description": "🚧: The name of the field group",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.labelField.description": "🚧: The name of the field to be used as display value",
"setting.frontMatter.taxonomy.frontMatterType.markdownDescription": "front matterの形式を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.frontmattertype)",
"setting.frontMatter.taxonomy.indentArrays.markdownDescription": "front matterメタデータが配列の場合はインデント字下げさせます。規定値はtrueです。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.indentarrays)",
"setting.frontMatter.taxonomy.modifiedField.markdownDescription": "🚧: This setting is used to define the modified date field of your articles. [ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.modifiedfield)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.markdownDescription": "引用符を付与しないメタデータを指定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.nopropertyvaluequotes)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.items.description": "引用符を削除したいプロパティの名前。",
"setting.frontMatter.taxonomy.seoContentLengh.markdownDescription": "最適な記事の長さを指定します。2021年のSEOでは、1,760語から2,400語の間が最も理想的とされています。-1に設定するとオフになります。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seocontentlengh)",
"setting.frontMatter.taxonomy.seoDescriptionField.markdownDescription": "ページのSEO情報のディスクリプションに使うフィールドの名前を指定します。規定値は'description'です。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionfield)",
"setting.frontMatter.taxonomy.seoDescriptionLength.markdownDescription": "SEOに適したディスクリプションの文字数を設定します。`-1`に設定するとオフになります。)[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionlength)",
"setting.frontMatter.taxonomy.seoSlugLength.markdownDescription": "SEOに適したスラッグの文字数を設定します。`-1`に設定するとオフになります。)[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seosluglength)",
"setting.frontMatter.taxonomy.seoTitleField.markdownDescription": "ページのSEO情報のタイトルに使うフィールドの名前を指定します。規定値は'title'です。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlefield)",
"setting.frontMatter.taxonomy.seoTitleLength.markdownDescription": "SEOに適したタイトルの文字数を設定します。`-1`に設定するとオフになります。)[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlelength)",
"setting.frontMatter.taxonomy.slugPrefix.markdownDescription": "スラッグに付与する接頭辞を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugprefix)",
"setting.frontMatter.taxonomy.slugSuffix.markdownDescription": "スラッグに付与する接尾辞を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugsuffix)",
"setting.frontMatter.taxonomy.tags.markdownDescription": "Front Matterで利用するタグを管理します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.telemetry.disable.markdownDescription": "利用状況の送信をオフにします。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.telemetry.disable)",
"setting.frontMatter.templates.enabled.markdownDescription": "テンプレート機能を利用します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.enabled)",
"setting.frontMatter.templates.folder.markdownDescription": "テンプレートを保存するフォルダーを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.folder)",
"setting.frontMatter.templates.prefix.markdownDescription": "新しい記事の作成時、ファイル名に付与する接頭辞を設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.prefix)",
"setting.frontMatter.dashboard.mediaSnippet.deprecationMessage": "🚧: This setting is deprecated and will be removed in the next major version. Please define your media snippet in the `frontMatter.content.snippet` setting.",
"setting.frontMatter.taxonomy.dateField.deprecationMessage": "🚧: This setting is deprecated and will be removed in the next major version. Please use the new `isPublishDate` settings instead in your content types date fields.",
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "🚧: This setting is deprecated and will be removed in the next major version. Please use the new `isModifiedDate` settings instead in your content types date fields.",
"setting.frontMatter.global.disabledNotifications.markdownDescription": "🚧: This is an array with the notifications types that can be disabled for Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.disablednotifications)",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "🚧: Specify the name of the custom field type to use."
}

243
package.nls.json Normal file
View File

@@ -0,0 +1,243 @@
{
"command.frontMatter.project.switch": "Switch project",
"command.frontMatter.config.reload": "Reload config",
"command.frontMatter.authenticate": "Authenticate",
"command.frontMatter.contenttype.generate": "Generate content type from current file",
"command.frontMatter.contenttype.addMissingFields": "Add missing fields from front matter to content type",
"command.frontMatter.contenttype.setContentType": "Set the content type to use for the current file",
"command.frontMatter.markup.blockquote": "Blockquote",
"command.frontMatter.markup.bold": "Bold",
"command.frontMatter.dashboard.close": "Close dashboard",
"command.frontMatter.markup.code": "Code",
"command.frontMatter.markup.codeblock": "Codeblock",
"command.frontMatter.markup.hyperlink": "Hyperlink",
"command.frontMatter.collapseSections": "Collapse sections",
"command.frontMatter.initTemplate": "Initialize the template folder",
"command.frontMatter.createTemplate": "Create template from current file",
"command.frontMatter.createCategory": "Create category",
"command.frontMatter.createContent": "Create new content from defined content type or template",
"command.frontMatter.createTag": "Create tag",
"command.frontMatter.diagnostics": "Diagnostic logging",
"command.frontMatter.exportTaxonomy": "Export all tags & categories to your settings",
"command.frontMatter.createFromTemplate": "New article from template",
"command.frontMatter.registerFolder": "Register folder",
"command.frontMatter.unregisterFolder": "Unregister folder",
"command.frontMatter.generateSlug": "Generate slug based on content title",
"command.frontMatter.markup.heading": "Heading",
"command.frontMatter.init": "Initialize project",
"command.frontMatter.insertCategories": "Insert categories",
"command.frontMatter.insertMedia": "Insert media into your content",
"command.frontMatter.insertSnippet": "Insert snippet into your content",
"command.frontMatter.insertTags": "Insert tags",
"command.frontMatter.markup.italic": "Italic",
"command.frontMatter.dashboard": "Open dashboard",
"command.frontMatter.dashboard.data": "Open data dashboard",
"command.frontMatter.dashboard.media": "Open media dashboard",
"command.frontMatter.dashboard.snippets": "Open snippets dashboard",
"command.frontMatter.dashboard.taxonomy": "Open taxonomies dashboard",
"command.frontMatter.markup.orderedlist": "Ordered list",
"command.frontMatter.markup.options": "Other markup options",
"command.frontMatter.preview": "Preview content",
"command.frontMatter.chatbot": "Ask the Front Matter AI for help",
"command.frontMatter.promoteSettings": "Promote settings from local to team level",
"command.frontMatter.remap": "Remap or remove tag/category in all articles",
"command.frontMatter.setLastModifiedDate": "Set lastmod date",
"command.frontMatter.markup.strikethrough": "Strikethrough",
"command.frontMatter.mode.switch": "Switch mode",
"command.frontMatter.markup.tasklist": "Task list",
"command.frontMatter.markup.unorderedlist": "Unordered list",
"command.frontMatter.git.sync": "Sync",
"command.frontMatter.cache.clear": "Clear cache",
"settings.configuration.title": "Front Matter: use frontmatter.json for shared team settings",
"setting.frontMatter.projects.markdownDescription": "Specify the list of projects to load in the Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.projects)",
"setting.frontMatter.projects.items.properties.name.markdownDescription": "Specify the name of the project.",
"setting.frontMatter.projects.items.properties.default.markdownDescription": "Specify if this project is the default project to load.",
"setting.frontMatter.sponsors.ai.enabled.markdownDescription": "Specify if you want to enable AI suggestions. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.sponsors.ai.enabled)",
"setting.frontMatter.extensibility.scripts.markdownDescription": "Specify the list of scripts to load in the Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extensibility.scripts)",
"setting.frontMatter.experimental.markdownDescription": "Specify if you want to enable the experimental features. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.experimental)",
"setting.frontMatter.extends.markdownDescription": "Specify the list of paths/URLs to extend the Front Matter CMS config. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extends)",
"setting.frontMatter.content.autoUpdateDate.markdownDescription": "Specify if you want to automatically update the modified date of your article/page (only content located in your content folder). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.autoupdatedate)",
"setting.frontMatter.content.defaultFileType.markdownDescription": "Specify the default file type for the content to create. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultfiletype)",
"setting.frontMatter.content.defaultSorting.markdownDescription": "Specify the default sorting option for the content dashboard. You can use one of the values from the enum or define your own ID. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultsorting)",
"setting.frontMatter.content.draftField.markdownDescription": "Define the draft field you want to use to manage your content. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.draftfield)",
"setting.frontMatter.content.draftField.properties.type.description": "Type of the draft field you want to use",
"setting.frontMatter.content.draftField.properties.name.description": "Name of the field to use",
"setting.frontMatter.content.draftField.properties.invert.description": "By default the draft field is set to true when the content is a draft. Set this to true to set it to false.",
"setting.frontMatter.content.draftField.properties.choices.description": "List of choices for the field",
"setting.frontMatter.content.fmHighlight.markdownDescription": "Specify if you want to highlight the Front Matter in the Markdown file. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.fmhighlight)",
"setting.frontMatter.content.hideFm.markdownDescription": "Specify if you want to hide the Front Matter in the Markdown file. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefm)",
"setting.frontMatter.content.hideFmMessage.markdownDescription": "Specify the message to display when the Front Matter is hidden. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefmMessage)",
"setting.frontMatter.content.pageFolders.markdownDescription": "This array of folders defines where the extension can retrieve or create new pages. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.pagefolders)",
"setting.frontMatter.content.pageFolders.items.properties.title.description": "Name of the folder",
"setting.frontMatter.content.pageFolders.items.properties.path.description": "Path of the folder",
"setting.frontMatter.content.pageFolders.items.properties.excludeSubdir.description": "Exclude sub-directories",
"setting.frontMatter.content.pageFolders.items.properties.previewPath.description": "Defines a custom preview path for the folder.",
"setting.frontMatter.content.pageFolders.items.properties.filePrefix.description": "Defines a prefix for the file name.",
"setting.frontMatter.content.pageFolders.items.properties.contentTypes.description": "Defines which content types can be used for the current location. If not defined, all content types will be available.",
"setting.frontMatter.content.placeholders.markdownDescription": "This array of placeholders defines the placeholders that you can use in your content types and templates for automatically populating your content its front matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.placeholders)",
"setting.frontMatter.content.placeholders.items.properties.id.description": "ID of the placeholder, in your content type or template, use it as follows: {{placeholder}}",
"setting.frontMatter.content.placeholders.items.properties.value.description": "The placeholder its value",
"setting.frontMatter.content.placeholders.items.properties.script.description": "The script to execute to get the value of the placeholder",
"setting.frontMatter.content.publicFolder.markdownDescription": "Specify the folder name where all your assets are located. For instance in Hugo this is the `static` folder. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.publicfolder)",
"setting.frontMatter.content.publicFolder.properties.path.description": "Specify the path of the assets folder",
"setting.frontMatter.content.publicFolder.properties.relative.description": "Defines if the path to your media files be relative to the content file?",
"setting.frontMatter.snippets.wrapper.enabled.markdownDescription": "Specify if you want to wrap the snippets. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.snippets.wrapper.enabled)",
"setting.frontMatter.content.snippets.markdownDescription": "Define the snippets you want to use in your content. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.snippets)",
"setting.frontMatter.content.sorting.markdownDescription": "Define the sorting options for your dashboard content. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.sorting)",
"setting.frontMatter.content.sorting.items.properties.id.description": "The ID of the sorting option. This will be used for the storing the last used sorting option or the default option.",
"setting.frontMatter.content.sorting.items.properties.title.description": "Name of the sorting label",
"setting.frontMatter.content.sorting.items.properties.name.description": "Name of the metadata field to sort by",
"setting.frontMatter.content.sorting.items.properties.order.description": "Order of the sorting",
"setting.frontMatter.content.sorting.items.properties.type.description": "Type of the field value",
"setting.frontMatter.content.supportedFileTypes.markdownDescription": "Specify the file types that you want to use in Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.supportedfiletypes)",
"setting.frontMatter.content.wysiwyg.markdownDescription": "Specifies if you want to enable/disable the What You See, Is What You Get (WYSIWYG) markdown controls. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.wysiwyg)",
"setting.frontMatter.custom.scripts.markdownDescription": "Specify the path to a Node.js script to execute. The current file path will be provided as an argument. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.custom.scripts)",
"setting.frontMatter.custom.scripts.items.properties.id.description": "ID of the script.",
"setting.frontMatter.custom.scripts.items.properties.title.description": "Title you want to give to your script. Will be shown as the title of the button.",
"setting.frontMatter.custom.scripts.items.properties.script.description": "Path to the script to execute",
"setting.frontMatter.custom.scripts.items.properties.nodeBin.description": "Path to the node executable. This is required when using NVM, so that there is no confusion of which node version to use. (deprecated: use the command property instead)",
"setting.frontMatter.custom.scripts.items.properties.bulk.description": "Run the script for all content files",
"setting.frontMatter.custom.scripts.items.properties.output.description": "Define where you want to output your script output. Default is a notification, but you can specify to show it in an editor panel.",
"setting.frontMatter.custom.scripts.items.properties.outputType.description": "The type of output for the editor panel. Can be used to change it to 'markdown' for example",
"setting.frontMatter.custom.scripts.items.properties.type.description": "The type for which the script will be used.",
"setting.frontMatter.custom.scripts.items.properties.command.description": "The type of script you want to execute.",
"setting.frontMatter.custom.scripts.items.properties.hidden.description": "Hide the action from the UI",
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.type.description": "The environment type for which the script needs to be used",
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.script.description": "Path to the script to execute",
"setting.frontMatter.dashboard.content.pagination.markdownDescription": "Specify if you want to enable/disable pagination for your content. You can define your page number up to 52. Default items per page is `16`. Disabling the pagination can be done by setting it to `false`. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.pagination)",
"setting.frontMatter.dashboard.content.cardTags.markdownDescription": "Specify the name of the metadata field that will be used to show the tags on the content card. When empty or null, it will hide the tags from the card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.cardtags)",
"setting.frontMatter.dashboard.content.card.fields.state.markdownDescription": "Specify if you want to show the state/draft status on the content card view. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.state)",
"setting.frontMatter.dashboard.content.card.fields.date.markdownDescription": "Specify if you want to show the date on the content card view. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.date)",
"setting.frontMatter.dashboard.content.card.fields.description.markdownDescription": "Specify the name of the metadata field that will be used to show the description on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.description)",
"setting.frontMatter.dashboard.content.card.fields.title.markdownDescription": "Specify the name of the metadata field that will be used to show the title on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.title)",
"setting.frontMatter.dashboard.mediaSnippet.markdownDescription": "Specify the a snippet for your custom media insert markup. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.mediasnippet)",
"setting.frontMatter.dashboard.mediaSnippet.items.description": "Use the `{mediaUrl}`, `{caption}`, `{alt}`, `{filename}`, `{mediaHeight}`, and `{mediaWidth}` placeholders in your snippet to automatically insert the media information.",
"setting.frontMatter.dashboard.openOnStart.markdownDescription": "Specify if you want to open the dashboard when you start VS Code. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.openonstart)",
"setting.frontMatter.data.files.markdownDescription": "Specify the data files you want to use for your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.files)",
"setting.frontMatter.data.files.items.properties.id.description": "Your unique ID you want to use for your data file.",
"setting.frontMatter.data.files.items.properties.title.description": "Title you want to give to your data file.",
"setting.frontMatter.data.files.items.properties.labelField.description": "The field you want to use as label for your data entries.",
"setting.frontMatter.data.files.items.properties.file.description": "Path to the file to load. Only JSON or YAML files are supported.",
"setting.frontMatter.data.files.items.properties.fileType.description": "Defines how you want to parse the file. JSON is the default.",
"setting.frontMatter.data.files.items.properties.schema.description": "The JSON schema for your data which will be used to render the data form.",
"setting.frontMatter.data.files.items.properties.schema.properties.title.description": "Title of the form.",
"setting.frontMatter.data.files.items.properties.schema.properties.type.description": "Defines the type of the form. Default is 'object'.",
"setting.frontMatter.data.files.items.properties.schema.properties.required.description": "Defines the required fields for the form.",
"setting.frontMatter.data.files.items.properties.schema.properties.properties.description": "Defines the fields of the form.",
"setting.frontMatter.data.files.items.properties.type.description": "If you are using data types, you can specify your type ID.",
"setting.frontMatter.data.files.items.properties.singleEntry.description": "If you want to use a single entry for your data file.",
"setting.frontMatter.data.folders.markdownDescription": "Specify the data folders you want to use for your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.folders)",
"setting.frontMatter.data.folders.items.properties.id.description": "Your unique ID you want to use for your data folder.",
"setting.frontMatter.data.folders.items.properties.labelField.description": "The field you want to use as label for your data entries.",
"setting.frontMatter.data.folders.items.properties.path.description": "Path to the folder to load files.",
"setting.frontMatter.data.folders.items.properties.type.description": "If you are using data types, you can specify your type ID.",
"setting.frontMatter.data.folders.items.properties.singleEntry.description": "If you want to use a single entry for your data files in the folder.",
"setting.frontMatter.data.types.markdownDescription": "Specify the data types. These types can be used in for your data files. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.types)",
"setting.frontMatter.data.types.items.properties.id.description": "Your unique ID you want to use for your data type.",
"setting.frontMatter.file.preserveCasing.markdownDescription": "Specify if you want to preserve the casing of your file names from the title. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.file.preservecasing)",
"setting.frontMatter.framework.id.markdownDescription": "Specify the ID of your static site generator or framework you are using for your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.id)",
"setting.frontMatter.framework.startCommand.markdownDescription": "Specify the command you want to use to start your static site generator or framework. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.startcommand)",
"setting.frontMatter.git.enabled.markdownDescription": "Specify if you want to use the Git actions for your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.enabled)",
"setting.frontMatter.git.commitMessage.markdownDescription": "Specify the commit message you want to use for the sync. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.commitmessage)",
"setting.frontMatter.git.submodule.pull.markdownDescription": "Specify if you want to pull submodules when syncing. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.pull)",
"setting.frontMatter.git.submodule.push.markdownDescription": "Specify if you want to push submodules when syncing. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.push)",
"setting.frontMatter.git.submodule.branch.markdownDescription": "Specify the submodule branch to checkout. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.branch)",
"setting.frontMatter.git.submodule.folder.markdownDescription": "Specify the submodule folder of your content, this can be handy when you are using multiple submodules. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.folder)",
"setting.frontMatter.global.activeMode.markdownDescription": "Specify the activated mode of Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.activemode)",
"setting.frontMatter.global.modes.markdownDescription": "Specify the modes you want to use for Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.modes)",
"setting.frontMatter.global.modes.items.properties.id.description": "The ID of your mode.",
"setting.frontMatter.global.modes.items.properties.features.description": "The features you want to use for your mode.",
"setting.frontMatter.global.notifications.markdownDescription": "Specifies the notifications you want to see. By default, all notifications types will be shown. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.notifications)",
"setting.frontMatter.global.disabledNotifications.markdownDescription": "This is an array with the notifications types that can be disabled for Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.disablednotifications)",
"setting.frontMatter.media.defaultSorting.markdownDescription": "Specify the default sorting option for the media dashboard. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.defaultsorting)",
"setting.frontMatter.media.supportedMimeTypes.markdownDescription": "Specify the mime types to support for the media files. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.supportedmimetypes)",
"setting.frontMatter.panel.freeform.markdownDescription": "Specifies if you want to allow yourself from entering unknown tags/categories in the tag picker (when enabled, you will have the option to store them afterwards). Default: true. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.freeform)",
"setting.frontMatter.preview.host.markdownDescription": "Specify the host URL (example: http://localhost:1313) to be used when opening the preview. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.host)",
"setting.frontMatter.preview.pathName.markdownDescription": "Specify the path you want to add after the host and before your slug. This can be used for instance to include the year/month like: `yyyy/MM`. The date will be generated based on the article its date field value. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.pathname)",
"setting.frontMatter.site.baseURL.markdownDescription": "Specify the base URL of your site, this will be used for SEO checks. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.site.baseurl)",
"setting.frontMatter.taxonomy.alignFilename.markdownDescription": "Align the filename with the new slug when it gets generated. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.alignfilename)",
"setting.frontMatter.taxonomy.categories.markdownDescription": "Specifies the categories which can be used in the Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.categories)",
"setting.frontMatter.taxonomy.commaSeparatedFields.markdownDescription": "Specify the fields names that Front Matter should treat as a comma-separated array. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.commaseparatedfields)",
"setting.frontMatter.taxonomy.commaSeparatedFields.items.description": "Name of the fields you want to use as comma-separated arrays.",
"setting.frontMatter.taxonomy.contentTypes.markdownDescription": "Specify the type of contents you want to use for your articles/pages/etc. Make sure the `type` is correctly set in your front matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.contenttypes)",
"setting.frontMatter.taxonomy.contentTypes.items.description": "Define the content types you want to use in Front Matter.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.name.description": "Define the type of field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fileType.description": "Specifies the type of content you want to create.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.description": "Define the fields of the content type",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.description": "Define the content types you want to use in Front Matter.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.type.description": "Define the type of field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.name.description": "Name of the field to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.title.description": "Title to show in the UI",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.description.description": "Description to show in the UI",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.default.description": "Default value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.description": "Define your choices",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.id.description": "The choice ID",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.title.description": "The choice title",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.single.description": "Is a single line field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.wysiwyg.description": "Is a WYSIWYG field (HTML output)",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.multiple.description": "Do you allow to select multiple values?",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isPreviewImage.description": "Specify if the image field can be used as preview. Be aware, you can only have one preview image per content type.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.hidden.description": "Do you want to hide the field from the metadata section?",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyId.description": "The ID of your taxonomy field. It cannot contain the \"tags\" or \"categories\" value.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.fileExtensions.description": "Specify the file extensions to allow for the file picker",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.fieldGroup.description": "The ID(s) of your field group(s) defined in the `frontMatter.taxonomy.fieldGroups` setting",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataType.description": "The ID(s) of your data type(s) defined in the `frontMatter.data.types` setting",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.description": "Specify the options for the number field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.isDecimal.description": "Specify if the number is a decimal",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.min.description": "The minimum value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.max.description": "The maximum value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.numberOptions.properties.step.description": "The step value",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyLimit.description": "Limit the number of taxonomies to select. Set to 0 to allow unlimited.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isPublishDate.description": "Specify if the field is the publish date field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isModifiedDate.description": "Specify if the field is the modified date field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileId.description": "Specify the ID of the data file to use for this field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileKey.description": "Specify the key of the data file to use for this field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dataFileValue.description": "Specify the property name that will be used to show the value for the field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.editable.description": "Specify if the field is editable",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.encodeEmoji.description": "Specify if the field should encode emoji",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.dateFormat.description": "Specify the date format to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.required.description": "Specify if the field is required",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeName.description": "Specify the content type name to filter content for the contentRelationship field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeValue.description": "Specify the value to insert for the contentRelationship field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.description": "Specify the conditions to show the field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.fieldRef.description": "The field ID to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.operator.description": "The operator to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.value.description": "The value to compare",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.caseSensitive.description": "Specify if the comparison is case sensitive. Default: true",
"setting.frontMatter.taxonomy.contentTypes.items.properties.pageBundle.description": "Specify if you want to create a folder when creating new content.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.previewPath.description": "Defines a custom preview path for the content type.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.template.description": "An optional template that can be used for creating new content.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.postScript.description": "An optional post script that can be used after new content creation.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.filePrefix.description": "Defines a prefix for the file name.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.defaultFileName.description": "Default file name to use when creating new content.",
"setting.frontMatter.taxonomy.customTaxonomy.markdownDescription": "Specify the custom taxonomy field data. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.id.description": "ID for your taxonomy field. It cannot contain the \"tags\" or \"categories\" value.",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.options.description": "Options from which you can pick.",
"setting.frontMatter.taxonomy.dateField.markdownDescription": "This setting is used to define the publishing date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.datefield)",
"setting.frontMatter.taxonomy.dateFormat.markdownDescription": "Specify the date format for your articles. Check [date-fns formating](https://date-fns.org/v2.0.1/docs/format) for more information. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.dateformat)",
"setting.frontMatter.taxonomy.fieldGroups.markdownDescription": "Define the field groups you want to use for your block fields. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.fieldgroups)",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.id.description": "The name of the field group",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.labelField.description": "The name of the field to be used as display value",
"setting.frontMatter.taxonomy.frontMatterType.markdownDescription": "Specify the type of Front Matter to use. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.frontmattertype)",
"setting.frontMatter.taxonomy.indentArrays.markdownDescription": "Specify if arrays in front matter are indented. Default: true. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.indentarrays)",
"setting.frontMatter.taxonomy.modifiedField.markdownDescription": "This setting is used to define the modified date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.modifiedfield)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.markdownDescription": "Specify the properties from which quotes need to be removed. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.nopropertyvaluequotes)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.items.description": "Name of the properties you want to remove quotes from.",
"setting.frontMatter.taxonomy.seoContentLengh.markdownDescription": "Specifies the optimal minimum length for your articles. Between 1,760 words 2,400 is the absolute ideal article length for SEO in 2021. (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seocontentlengh)",
"setting.frontMatter.taxonomy.seoDescriptionField.markdownDescription": "Specifies the name of the SEO description field for your page. Default is 'description'. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionfield)",
"setting.frontMatter.taxonomy.seoDescriptionLength.markdownDescription": "Specifies the optimal description length for SEO (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionlength)",
"setting.frontMatter.taxonomy.seoSlugLength.markdownDescription": "Specifies the optimal slug length for SEO (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seosluglength)",
"setting.frontMatter.taxonomy.seoTitleField.markdownDescription": "Specifies the name of the SEO title field for your page. Default is 'title'. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlefield)",
"setting.frontMatter.taxonomy.seoTitleLength.markdownDescription": "Specifies the optimal title length for SEO (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlelength)",
"setting.frontMatter.taxonomy.slugPrefix.markdownDescription": "Specify a prefix for the slug. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugprefix)",
"setting.frontMatter.taxonomy.slugSuffix.markdownDescription": "Specify a suffix for the slug. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugsuffix)",
"setting.frontMatter.taxonomy.tags.markdownDescription": "Specifies the tags which can be used in the Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.telemetry.disable.markdownDescription": "Specify if you want to disable the telemetry. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.telemetry.disable)",
"setting.frontMatter.templates.enabled.markdownDescription": "Specify if you want to use templates. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.enabled)",
"setting.frontMatter.templates.folder.markdownDescription": "Specify the folder to use for your article templates. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.folder)",
"setting.frontMatter.templates.prefix.markdownDescription": "Specify the prefix you want to add for your new article filenames. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.prefix)",
"setting.frontMatter.dashboard.mediaSnippet.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please define your media snippet in the `frontMatter.content.snippet` setting.",
"setting.frontMatter.taxonomy.dateField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isPublishDate` settings instead in your content types date fields.",
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isModifiedDate` settings instead in your content types date fields.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "Specify the name of the custom field type to use."
}

8237
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,10 @@
const tailwindcss = require('tailwindcss');
module.exports = {
plugins: [
require('postcss-nested'),
tailwindcss('./tailwind.config.js'),
require('autoprefixer'),
],
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
}
};

View File

@@ -8,14 +8,14 @@ const version = packageJson.version.split('.');
packageJson.version = `${version[0]}.${version[1]}.${process.argv[process.argv.length-1].substr(0, 7)}`;
packageJson.preview = true;
packageJson.name = "vscode-front-matter-beta";
packageJson.displayName = `${packageJson.displayName} BETA`;
packageJson.displayName = `${packageJson.displayName} (BETA)`;
packageJson.description = `BETA Version of Front Matter. ${packageJson.description}`;
packageJson.icon = "assets/frontmatter-beta.png";
packageJson.homepage = "https://beta.frontmatter.codes";
console.log(packageJson.version);
core.summary.addHeading(`Version info`).addDetails(`${packageJson.version}`);
core.summary.addHeading(`Version info`).addRaw(`Version: ${packageJson.version}`).write();
const scripts = packageJson.scripts;
for (const key in scripts) {

View File

@@ -0,0 +1,60 @@
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const cheerio = require('cheerio');
const files = glob.sync('src/**/*.ts*');
console.log('Total files:', files.length);
const enumFile = fs.createWriteStream(path.join(__dirname, '../localization.log'));
// for (const file of files) {
// // Get the file and its contents
// const fileContent = fs.readFileSync(path.join(__dirname, "../", file), 'utf8');
// const regex = />[A-Za-z]{1,}/g;
// const matches = fileContent.match(regex);
// if (matches && matches.length > 0) {
// enumFile.write(`File: ${path.join(__dirname, "../", file)}\n`);
// enumFile.write(`Matches: ${matches.toString()}\n`);
// enumFile.write(`\n`);
// }
// }
for (const file of files) {
const fileContent = fs.readFileSync(path.join(__dirname, "../", file), 'utf8');
const $ = cheerio.load(fileContent, {
recognizeSelfClosing: true,
xmlMode: true,
});
const matches = [];
$('*').each(function () {
const node = $(this);
let text = node.contents().first().text();
text = text.trim();
if (text &&
!text.startsWith('{') &&
!text.includes(`{`) &&
!text.includes(`}`) &&
!text.includes(`(`) &&
!text.includes(`)`) &&
text.split('\n').length === 1) {
matches.push(`Text: ${text}\n`);
}
});
if (matches && matches.length > 0) {
enumFile.write(`File: ${path.join(__dirname, "../", file)}\n`);
enumFile.write(`${matches.join('')}\n`);
enumFile.write(`\n`);
}
}
enumFile.close();

View File

@@ -0,0 +1,41 @@
const fs = require('fs');
const path = require('path');
const camlCase = (str) => {
const words = str.split('.');
const firstWord = words.shift();
const rest = words.map((word) => {
return word.charAt(0).toUpperCase() + word.slice(1);
});
return firstWord + rest.join('');
};
(async () => {
// Get the EN file
const enFile = fs.readFileSync(path.join(__dirname, '../l10n/bundle.l10n.json'), 'utf8');
// Parse the EN file
const en = JSON.parse(enFile);
const keys = Object.keys(en);
// Create an enum file
const enumFile = fs.createWriteStream(path.join(__dirname, '../src/localization/localization.enum.ts'));
// Write the enum file header
enumFile.write(`export enum LocalizationKey {\n`);
// Write the enum values
keys.forEach((key, index) => {
enumFile.write(` /**\n`);
enumFile.write(` * ${en[key]}\n`);
enumFile.write(` */\n`);
enumFile.write(` ${camlCase(key)} = '${key}'${index === keys.length - 1 ? '' : ','}\n`);
});
// Write the enum file footer
enumFile.write(`}\n`);
// Close the enum file
enumFile.close();
})();

View File

@@ -0,0 +1,43 @@
const packageJson = require('../package.json');
for (const key of Object.keys(packageJson.contributes.configuration.properties)) {
const type = packageJson.contributes.configuration.properties[key].type;
if (type.includes('object') || type.includes('array')) {
console.log(`${key} - ${packageJson.contributes.configuration.properties[key].type}`);
}
}
// TO IGNORE
// frontMatter.extends - array
// frontMatter.dashboard.mediaSnippet - array
// TO PROCESS AS A WHOLE OBJECT
// frontMatter.content.draftField - object
// frontMatter.content.supportedFileTypes - array
// frontMatter.global.notifications - array
// frontMatter.global.disabledNotifications - array
// frontMatter.media.supportedMimeTypes - array
// frontMatter.taxonomy.commaSeparatedFields - array
// MERGE ARRAYS
// frontMatter.taxonomy.categories - array
// frontMatter.taxonomy.tags - array
// frontMatter.taxonomy.noPropertyValueQuotes - array
// PROCESS ITEM BY ITEM
// frontMatter.custom.scripts - array - id
// frontMatter.taxonomy.contentTypes - array,null - name
// frontMatter.data.files - array - id
// frontMatter.data.folders - array - id
// frontMatter.data.types - array - id
// frontMatter.content.pageFolders - array - path
// frontMatter.content.placeholders - array - id
// frontMatter.content.sorting - array - id
// frontMatter.global.modes - array - id
// frontMatter.taxonomy.fieldGroups - array - id
// frontMatter.taxonomy.customTaxonomy - array - id
// frontMatter.content.snippets - object

View File

@@ -0,0 +1,70 @@
const fs = require('fs');
const path = require('path');
const glob = require('glob');
(async () => {
// Get all the files from the l10n directory
const files = fs.readdirSync(path.join(__dirname, '../l10n'));
// Get the EN file
const enFile = fs.readFileSync(path.join(__dirname, '../l10n/bundle.l10n.json'), 'utf8');
const enContent = JSON.parse(enFile);
const enKeys = Object.keys(enContent);
for (const file of files) {
if (file.endsWith(`bundle.l10n.json`)) {
continue;
}
// Get the file content
const fileContent = fs.readFileSync(path.join(__dirname, `../l10n/${file}`), 'utf8');
let content = {};
try {
content = JSON.parse(fileContent);
} catch (e) {
// Ignore the error
}
// Loop through the EN keys
for (const key of enKeys) {
// If the key does not exist in the file, add it
if (!content[key]) {
content[key] = `🚧: ${enContent[key]}`;
}
}
// Write the file
fs.writeFileSync(path.join(__dirname, `../l10n/${file}`), JSON.stringify(content, null, 2), 'utf8');
}
// Package JSON
const enPkgFile = fs.readFileSync(path.join(__dirname, '../package.nls.json'), 'utf8');
const enPkgContent = JSON.parse(enPkgFile);
const enPkgKeys = Object.keys(enPkgContent);
const pkgFiles = glob.sync(path.join(__dirname, '../package.nls.*.json'));
for (const file of pkgFiles) {
const fileContent = fs.readFileSync(file, 'utf8');
let content = {};
try {
content = JSON.parse(fileContent);
} catch (e) {
// Ignore the error
}
// Loop through the EN keys
for (const key of enPkgKeys) {
// If the key does not exist in the file, add it
if (!content[key]) {
content[key] = `🚧: ${enPkgContent[key]}`;
}
}
// Write the file
fs.writeFileSync(file, JSON.stringify(content, null, 2), 'utf8');
}
})();

View File

@@ -0,0 +1,13 @@
const fs = require('fs');
const { exec } = require('node:child_process');
const { join } = require('path');
const localFile = '../l10n/bundle.l10n.json';
console.log(`Watching for file changes on ${localFile}`);
exec(`npm run localization:generate`)
fs.watchFile(join(__dirname, localFile), (curr, prev) => {
console.log(`update enum`)
exec(`npm run localization:generate`)
});

View File

@@ -1,14 +1,25 @@
import { Folders } from './Folders';
import { DEFAULT_CONTENT_TYPE } from './../constants/ContentType';
import { isValidFile } from './../helpers/isValidFile';
import { SETTING_AUTO_UPDATE_DATE, SETTING_MODIFIED_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_CONTENT_PLACEHOLDERS, TelemetryEvent } from './../constants';
import {
SETTING_AUTO_UPDATE_DATE,
SETTING_SLUG_UPDATE_FILE_NAME,
SETTING_TEMPLATES_PREFIX,
CONFIG_KEY,
SETTING_DATE_FORMAT,
SETTING_SLUG_PREFIX,
SETTING_SLUG_SUFFIX,
SETTING_CONTENT_PLACEHOLDERS,
TelemetryEvent
} from './../constants';
import * as vscode from 'vscode';
import { Field, TaxonomyType } from "../models";
import { format } from "date-fns";
import { ArticleHelper, Settings, SlugHelper } from '../helpers';
import { CustomPlaceholder, Field, TaxonomyType } from '../models';
import { format } from 'date-fns';
import { ArticleHelper, Settings, SlugHelper, TaxonomyHelper } from '../helpers';
import { Notifications } from '../helpers/Notifications';
import { extname, basename, parse, dirname } from 'path';
import { COMMAND_NAME, DefaultFields } from '../constants';
import { DashboardData } from '../models/DashboardData';
import { DashboardData, SnippetRange } from '../models/DashboardData';
import { DateHelper } from '../helpers/DateHelper';
import { parseWinPath } from '../helpers/parseWinPath';
import { Telemetry } from '../helpers/Telemetry';
@@ -16,14 +27,15 @@ import { ParsedFrontMatter } from '../parsers';
import { MediaListener } from '../listeners/panel';
import { NavigationType } from '../dashboardWebView/models';
import { processKnownPlaceholders } from '../helpers/PlaceholderHelper';
import { Position } from 'vscode';
import { SNIPPET } from '../constants/Snippet';
export class Article {
/**
* Insert taxonomy
*
* @param type
*/
* Insert taxonomy
*
* @param type
*/
public static async insert(type: TaxonomyType) {
const editor = vscode.window.activeTextEditor;
if (!editor) {
@@ -37,24 +49,29 @@ export class Article {
}
let options: vscode.QuickPickItem[] = [];
const matterProp: string = type === TaxonomyType.Tag ? "tags" : "categories";
const matterProp: string = type === TaxonomyType.Tag ? 'tags' : 'categories';
// Add the selected options to the options array
if (article.data[matterProp]) {
const propData = article.data[matterProp];
if (propData && propData.length > 0) {
options = [...propData].filter(p => p).map(p => ({
label: p,
picked: true
} as vscode.QuickPickItem));
options = [...propData]
.filter((p) => p)
.map(
(p) =>
({
label: p,
picked: true
} as vscode.QuickPickItem)
);
}
}
// Add all the known options to the selection list
const crntOptions = Settings.getTaxonomy(type);
const crntOptions = (await TaxonomyHelper.get(type)) || [];
if (crntOptions && crntOptions.length > 0) {
for (const crntOpt of crntOptions) {
if (!options.find(o => o.label === crntOpt)) {
if (!options.find((o) => o.label === crntOpt)) {
options.push({
label: crntOpt
});
@@ -63,18 +80,18 @@ export class Article {
}
if (options.length === 0) {
Notifications.info(`No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`);
Notifications.info(`No ${type === TaxonomyType.Tag ? 'tags' : 'categories'} configured.`);
return;
}
const selectedOptions = await vscode.window.showQuickPick(options, {
placeHolder: `Select your ${type === TaxonomyType.Tag ? "tags" : "categories"} to insert`,
placeHolder: `Select your ${type === TaxonomyType.Tag ? 'tags' : 'categories'} to insert`,
canPickMany: true,
ignoreFocusOut: true
});
if (selectedOptions) {
article.data[matterProp] = selectedOptions.map(o => o.label);
article.data[matterProp] = selectedOptions.map((o) => o.label);
}
ArticleHelper.update(editor, article);
@@ -94,21 +111,23 @@ export class Article {
return;
}
article = this.updateDate(article, true);
article = this.updateDate(article);
try {
ArticleHelper.update(editor, article);
} catch (e) {
Notifications.error(`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`);
Notifications.error(
`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`
);
}
}
/**
* Update the date in the front matter
* @param article
* @param article
*/
public static updateDate(article: ParsedFrontMatter, forceCreate: boolean = false) {
article.data = ArticleHelper.updateDates(article.data);
public static updateDate(article: ParsedFrontMatter) {
article.data = ArticleHelper.updateDates(article.data);
return article;
}
@@ -123,14 +142,11 @@ export class Article {
const updatedArticle = this.setLastModifiedDateInner(editor.document);
if (typeof updatedArticle === "undefined") {
if (typeof updatedArticle === 'undefined') {
return;
}
ArticleHelper.update(
editor,
updatedArticle as ParsedFrontMatter
);
ArticleHelper.update(editor, updatedArticle as ParsedFrontMatter);
}
public static async setLastModifiedDateOnSave(
@@ -138,7 +154,7 @@ export class Article {
): Promise<vscode.TextEdit[]> {
const updatedArticle = this.setLastModifiedDateInner(document);
if (typeof updatedArticle === "undefined") {
if (typeof updatedArticle === 'undefined') {
return [];
}
@@ -162,8 +178,10 @@ export class Article {
try {
cloneArticle.data[dateField] = Article.formatDate(new Date());
return cloneArticle;
} catch (e: any) {
Notifications.error(`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`);
} catch (e: unknown) {
Notifications.error(
`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`
);
}
}
@@ -193,11 +211,10 @@ export class Article {
/**
* Generate the slug based on the article title
*/
public static async updateSlug() {
Telemetry.send(TelemetryEvent.generateSlug);
public static async updateSlug() {
Telemetry.send(TelemetryEvent.generateSlug);
const updateFileName = Settings.get(SETTING_SLUG_UPDATE_FILE_NAME) as string;
const filePrefix = Settings.get<string>(SETTING_TEMPLATES_PREFIX);
const editor = vscode.window.activeTextEditor;
if (!editor) {
@@ -209,30 +226,41 @@ export class Article {
return;
}
let filePrefix = Settings.get<string>(SETTING_TEMPLATES_PREFIX);
const contentType = ArticleHelper.getContentType(article.data);
const titleField = "title";
filePrefix = ArticleHelper.getFilePrefix(filePrefix, editor.document.uri.fsPath, contentType);
const titleField = 'title';
const articleTitle: string = article.data[titleField];
const slugInfo = Article.generateSlug(articleTitle);
if (slugInfo && slugInfo.slug && slugInfo.slugWithPrefixAndSuffix) {
article.data["slug"] = slugInfo.slugWithPrefixAndSuffix;
article.data['slug'] = slugInfo.slugWithPrefixAndSuffix;
if (contentType) {
// Update the fields containing the slug placeholder
let fieldsToUpdate: Field[] = contentType.fields.filter(f => f.default === "{{slug}}");
const fieldsToUpdate: Field[] = contentType.fields.filter((f) => f.default === '{{slug}}');
for (const field of fieldsToUpdate) {
article.data[field.name] = slugInfo.slug;
}
// Update the fields containing a custom placeholder that depends on slug
const placeholders = Settings.get<{id: string, value: string}[]>(SETTING_CONTENT_PLACEHOLDERS);
const customPlaceholders = placeholders?.filter(p => p.value.includes("{{slug}}"));
const placeholders = Settings.get<CustomPlaceholder[]>(SETTING_CONTENT_PLACEHOLDERS);
const customPlaceholders = placeholders?.filter(
(p) => p.value && p.value.includes('{{slug}}')
);
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
for (const customPlaceholder of (customPlaceholders || [])) {
const customPlaceholderFields = contentType.fields.filter(f => f.default === `{{${customPlaceholder.id}}}`);
for (const customPlaceholder of customPlaceholders || []) {
const customPlaceholderFields = contentType.fields.filter(
(f) => f.default === `{{${customPlaceholder.id}}}`
);
for (const pField of customPlaceholderFields) {
article.data[pField.name] = customPlaceholder.value;
article.data[pField.name] = processKnownPlaceholders(article.data[pField.name], articleTitle, dateFormat);
article.data[pField.name] = processKnownPlaceholders(
article.data[pField.name],
articleTitle,
dateFormat
);
}
}
}
@@ -246,13 +274,13 @@ export class Article {
if (editor) {
const ext = extname(editor.document.fileName);
const fileName = basename(editor.document.fileName);
let slugName = slugInfo.slug.startsWith("/") ? slugInfo.slug.substring(1) : slugInfo.slug;
slugName = slugName.endsWith("/") ? slugName.substring(0, slugName.length - 1) : slugName;
let slugName = slugInfo.slug.startsWith('/') ? slugInfo.slug.substring(1) : slugInfo.slug;
slugName = slugName.endsWith('/') ? slugName.substring(0, slugName.length - 1) : slugName;
let newFileName = `${slugName}${ext}`;
if (filePrefix && typeof filePrefix === "string") {
newFileName = `${format(new Date(), DateHelper.formatUpdate(filePrefix) as string)}-${newFileName}`;
if (filePrefix && typeof filePrefix === 'string') {
newFileName = `${filePrefix}-${newFileName}`;
}
const newPath = editor.document.uri.fsPath.replace(fileName, newFileName);
@@ -263,13 +291,13 @@ export class Article {
await vscode.workspace.fs.rename(editor.document.uri, vscode.Uri.file(newPath), {
overwrite: false
});
} catch (e: any) {
Notifications.error(`Failed to rename file: ${e?.message || e}`);
} catch (e: unknown) {
Notifications.error(`Failed to rename file: ${(e as Error).message || e}`);
}
}
}
}
}
}
/**
* Retrieve the slug from the front matter
@@ -288,7 +316,7 @@ export class Article {
const parsedFile = parse(file);
if (parsedFile.name.toLowerCase() !== "index") {
if (parsedFile.name.toLowerCase() !== 'index') {
return parsedFile.name;
}
@@ -309,8 +337,8 @@ export class Article {
return;
}
const newDraftStatus = !article.data["draft"];
article.data["draft"] = newDraftStatus;
const newDraftStatus = !article.data['draft'];
article.data['draft'] = newDraftStatus;
ArticleHelper.update(editor, article);
}
@@ -323,6 +351,14 @@ export class Article {
if (document && ArticleHelper.isSupportedFile(document)) {
const autoUpdate = Settings.get(SETTING_AUTO_UPDATE_DATE);
// Is article located in one of the content folders
const folders = Folders.get();
const documentPath = parseWinPath(document.fileName);
const folder = folders.find((f) => documentPath.startsWith(f.path));
if (!folder) {
return;
}
if (autoUpdate) {
event.waitUntil(Article.setLastModifiedDateOnSave(document));
}
@@ -332,13 +368,17 @@ export class Article {
/**
* Format the date to the defined format
*/
public static formatDate(dateValue: Date): string {
public static formatDate(dateValue: Date, fieldDateFormat?: string): string {
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
if (dateFormat && typeof dateFormat === "string") {
if (fieldDateFormat) {
return format(dateValue, DateHelper.formatUpdate(fieldDateFormat) as string);
} else if (dateFormat && typeof dateFormat === 'string') {
return format(dateValue, DateHelper.formatUpdate(dateFormat) as string);
} else {
return typeof dateValue.toISOString === 'function' ? dateValue.toISOString() : dateValue?.toString();
return typeof dateValue.toISOString === 'function'
? dateValue.toISOString()
: dateValue?.toString();
}
}
@@ -346,65 +386,115 @@ export class Article {
* Insert an image from the media dashboard into the article
*/
public static async insertMedia() {
let editor = vscode.window.activeTextEditor;
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
const article = ArticleHelper.getFrontMatter(editor);
const contentType = article && article.data ? ArticleHelper.getContentType(article.data) : DEFAULT_CONTENT_TYPE;
const position = editor.selection.active;
await vscode.commands.executeCommand(COMMAND_NAME.dashboard, {
type: "media",
data: {
pageBundle: !!contentType.pageBundle,
filePath: editor.document.uri.fsPath,
fieldName: basename(editor.document.uri.fsPath),
position
}
} as DashboardData);
// Let the editor panel know you are selecting an image
MediaListener.getMediaSelection();
}
/**
* Insert a snippet into the article
*/
public static async insertSnippet() {
let editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
const contentType =
article && article.data ? ArticleHelper.getContentType(article.data) : DEFAULT_CONTENT_TYPE;
const position = editor.selection.active;
const selectionText = editor.document.getText(editor.selection);
const article = ArticleHelper.getFrontMatter(editor);
await vscode.commands.executeCommand(COMMAND_NAME.dashboard, {
type: NavigationType.Snippets,
type: 'media',
data: {
fileTitle: article?.data.title || "",
pageBundle: !!contentType.pageBundle,
filePath: editor.document.uri.fsPath,
fieldName: basename(editor.document.uri.fsPath),
position,
selection: selectionText
}
} as DashboardData);
}
// Let the editor panel know you are selecting an image
MediaListener.getMediaSelection();
}
/**
* Insert a snippet into the article
*/
public static async insertSnippet() {
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
let position = editor.selection.active;
const selectionText = editor.document.getText(editor.selection);
// Check for snippet wrapper
const selectionStart = editor.selection.start;
const docText = editor.document.getText();
const docTextLines = docText.split(`\n`);
const snippetEndAfterPos = docTextLines.findIndex((value: string, idx: number) => {
return value.includes(SNIPPET.wrapper.end) && idx >= selectionStart.line;
});
const snippetStartAfterPos = docTextLines.findIndex((value: string, idx: number) => {
return value.includes(SNIPPET.wrapper.start) && idx > selectionStart.line;
});
const linesBeforeSelection = docTextLines.slice(0, selectionStart.line + 1);
let snippetStartBeforePos = linesBeforeSelection
.reverse()
.findIndex((r) => r.includes(SNIPPET.wrapper.start));
if (snippetStartBeforePos > -1) {
snippetStartBeforePos = linesBeforeSelection.length - snippetStartBeforePos - 1;
}
let snippetInfo: { id: string; fields: any[] } | undefined = undefined;
let range: SnippetRange | undefined = undefined;
if (
snippetEndAfterPos > -1 &&
(snippetStartAfterPos > snippetEndAfterPos || snippetStartAfterPos === -1) &&
snippetStartBeforePos
) {
// Content was within a snippet block, get all the text
const snippetBlock = docTextLines.slice(snippetStartBeforePos, snippetEndAfterPos + 1);
const firstLine = snippetBlock[0];
range = {
start: new Position(snippetStartBeforePos, 0),
end: new Position(snippetEndAfterPos, snippetBlock[snippetBlock.length - 1].length)
};
const data = firstLine
.replace(`<!-- ${SNIPPET.wrapper.start} data:`, '')
.replace(' -->', '')
.replace(/'/g, '"');
snippetInfo = JSON.parse(data);
}
const article = ArticleHelper.getFrontMatter(editor);
await vscode.commands.executeCommand(COMMAND_NAME.dashboard, {
type: NavigationType.Snippets,
data: {
fileTitle: article?.data.title || '',
filePath: editor.document.uri.fsPath,
fieldName: basename(editor.document.uri.fsPath),
position,
range,
selection: selectionText,
snippetInfo
}
} as DashboardData);
}
/**
* Update the article date and return it
* @param article
* @param dateFormat
* @param field
* @param forceCreate
* @param article
* @param dateFormat
* @param field
* @param forceCreate
*/
private static articleDate(article: ParsedFrontMatter, field: string, forceCreate: boolean) {
if (typeof article.data[field] !== "undefined" || forceCreate) {
if (typeof article.data[field] !== 'undefined' || forceCreate) {
article.data[field] = Article.formatDate(new Date());
}
return article;

View File

@@ -1,11 +1,11 @@
import { commands, ExtensionContext } from 'vscode';
import { CONTEXT } from '../constants';
import { COMMAND_NAME, CONTEXT } from '../constants';
import { Extension } from '../helpers';
import { Credentials } from "../services/Credentials";
import fetch from "node-fetch";
import { ExplorerView } from '../explorerView/ExplorerView';
import { Credentials } from '../services/Credentials';
import fetch from 'node-fetch';
import { Dashboard } from './Dashboard';
import { SettingsListener } from '../listeners/panel';
import { PanelProvider } from '../panelWebView/PanelProvider';
export class Backers {
private static creds: Credentials | null = null;
@@ -17,7 +17,7 @@ export class Backers {
Backers.tryUsernameCheck();
context.subscriptions.push(
commands.registerCommand('frontMatter.authenticate', async () => {
commands.registerCommand(COMMAND_NAME.authenticate, async () => {
Backers.tryUsernameCheck();
})
);
@@ -26,16 +26,16 @@ export class Backers {
public static async tryUsernameCheck() {
try {
const username = await Backers.getUsername();
Backers.validate(username || "");
Backers.validate(username || '');
} catch (e) {
Backers.validate("");
Backers.validate('');
}
}
public static async getUsername() {
const octokit = await Backers.creds?.getOctokit();
const user = await octokit?.users.getAuthenticated();
if (user?.data?.login) {
return user?.data?.login;
}
@@ -52,18 +52,20 @@ export class Backers {
const isBeta = ext.isBetaVersion();
const response = await fetch(`https://${isBeta ? `beta.` : ``}frontmatter.codes/api/backers?backer=${username}`);
const response = await fetch(
`https://${isBeta ? `beta.` : ``}frontmatter.codes/api/backers?backer=${username}`
);
if (response.ok) {
const prevData = await ext.getState<boolean>(CONTEXT.backer, 'global');
await ext.setState(CONTEXT.backer, true, 'global');
if (!prevData) {
const explorerView = ExplorerView.getInstance();
if (explorerView.visible) {
const PanelView = PanelProvider.getInstance();
if (PanelView.visible) {
SettingsListener.getSettings();
}
if (Dashboard.isOpen) {
Dashboard.reload();
}
@@ -72,4 +74,4 @@ export class Backers {
ext.setState(CONTEXT.backer, false, 'global');
}
}
}
}

34
src/commands/Cache.ts Normal file
View File

@@ -0,0 +1,34 @@
import { commands } from 'vscode';
import { COMMAND_NAME, ExtensionState } from '../constants';
import { Extension, Notifications } from '../helpers';
export class Cache {
public static async registerCommands() {
const ext = Extension.getInstance();
const subscriptions = ext.subscriptions;
subscriptions.push(commands.registerCommand(COMMAND_NAME.clearCache, Cache.clear));
}
public static async get<T>(key: string, type: 'workspace' | 'global'): Promise<T | undefined> {
const ext = Extension.getInstance();
const cache = await ext.getState<T>(key, type);
return cache || undefined;
}
public static async set(key: string, data: unknown, type: 'workspace' | 'global' = 'workspace') {
await Extension.getInstance().setState(key, data, type);
}
public static async clear(showNotification: boolean = true) {
const ext = Extension.getInstance();
await ext.setState(ExtensionState.Dashboard.Pages.Cache, undefined, 'workspace', true);
await ext.setState(ExtensionState.Dashboard.Pages.Index, undefined, 'workspace', true);
await ext.setState(ExtensionState.Settings.Extends, undefined, 'workspace', true);
if (showNotification) {
Notifications.info('Cache cleared');
}
}
}

105
src/commands/Chatbot.ts Normal file
View File

@@ -0,0 +1,105 @@
import { Telemetry } from './../helpers/Telemetry';
import { TelemetryEvent, PreviewCommands, SETTING_EXPERIMENTAL } from './../constants';
import { join } from 'path';
import { commands, Uri, ViewColumn, window } from 'vscode';
import { Extension, Settings } from '../helpers';
import { WebviewHelper } from '@estruyf/vscode';
export class Chatbot {
/**
* Open the Chatbot in the editor
*/
public static async open(extensionPath: string) {
// Create the preview webview
const webView = window.createWebviewPanel(
'frontMatterChatbot',
'Front Matter AI - Ask me anything',
{
viewColumn: ViewColumn.Beside,
preserveFocus: true
},
{
enableScripts: true
}
);
webView.iconPath = {
dark: Uri.file(join(extensionPath, 'assets/icons/frontmatter-short-dark.svg')),
light: Uri.file(join(extensionPath, 'assets/icons/frontmatter-short-light.svg'))
};
const cspSource = webView.webview.cspSource;
webView.webview.onDidReceiveMessage((message) => {
switch (message.command) {
case PreviewCommands.toVSCode.open:
if (message.data) {
commands.executeCommand('vscode.open', message.data);
}
return;
}
});
const dashboardFile = 'dashboardWebView.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
const nonce = WebviewHelper.getNonce();
const ext = Extension.getInstance();
const isProd = ext.isProductionMode;
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
const extensionUri = ext.extensionPath;
const csp = [
`default-src 'none';`,
`img-src ${cspSource} http: https:;`,
`script-src ${
isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`
} 'unsafe-eval'`,
`style-src ${cspSource} 'self' 'unsafe-inline' http: https:`,
`connect-src https://* ${
isProd
? ``
: `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`
}`
];
let scriptUri = '';
if (isProd) {
scriptUri = webView.webview
.asWebviewUri(Uri.joinPath(extensionUri, 'dist', dashboardFile))
.toString();
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
}
// By default, the chatbot is seen as experimental
const experimental = true;
webView.webview.html = `
<!DOCTYPE html>
<html lang="en" style="width:100%;height:100%;margin:0;padding:0;">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="${csp.join('; ')}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Front Matter Docs Chatbot</title>
</head>
<body style="width:100%;height:100%;margin:0;padding:0;overflow:hidden">
<div id="app" data-type="chatbot" data-isProd="${isProd}" data-environment="${
isBeta ? 'BETA' : 'main'
}" data-version="${version.usedVersion}" ${
experimental ? `data-experimental="${experimental}"` : ''
} style="width:100%;height:100%;margin:0;padding:0;"></div>
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
</body>
</html>
`;
Telemetry.send(TelemetryEvent.openChatbot);
}
}

View File

@@ -1,9 +1,8 @@
import { commands, QuickPickItem, window } from 'vscode';
import { commands, QuickPickItem, window } from 'vscode';
import { COMMAND_NAME, SETTING_TEMPLATES_ENABLED } from '../constants';
import { Settings } from '../helpers';
export class Content {
public static async create() {
const templatesEnabled = await Settings.get(SETTING_TEMPLATES_ENABLED);
if (!templatesEnabled) {
@@ -11,15 +10,19 @@ export class Content {
return;
}
const options: QuickPickItem[] = [{
label: "Create content by content type",
description: "Select if you want to create new content by the available content type(s)"
}, {
label: "Create content by template",
description: "Select if you want to create new content by the available template(s)"
} as QuickPickItem];
const options: QuickPickItem[] = [
{
label: 'Create content by content type',
description: 'Select if you want to create new content by the available content type(s)'
},
{
label: 'Create content by template',
description: 'Select if you want to create new content by the available template(s)'
} as QuickPickItem
];
const selectedOption = await window.showQuickPick(options, {
title: 'Create content',
placeHolder: `Select how you want to create your new content`,
canPickMany: false,
ignoreFocusOut: true
@@ -35,4 +38,4 @@ export class Content {
return;
}
}
}

View File

@@ -1,20 +1,38 @@
import { SETTING_DASHBOARD_OPENONSTART, CONTEXT, ExtensionState } from '../constants';
import { join } from "path";
import { commands, Uri, ViewColumn, Webview, WebviewPanel, window } from "vscode";
import {
SETTING_DASHBOARD_OPENONSTART,
CONTEXT,
ExtensionState,
SETTING_EXPERIMENTAL,
SETTING_EXTENSIBILITY_SCRIPTS
} from '../constants';
import { join } from 'path';
import { commands, Uri, ViewColumn, Webview, WebviewPanel, window, workspace } from 'vscode';
import { Logger, Settings as SettingsHelper } from '../helpers';
import { DashboardCommand } from '../dashboardWebView/DashboardCommand';
import { Extension } from '../helpers/Extension';
import { WebviewHelper } from '@estruyf/vscode';
import { DashboardData } from '../models/DashboardData';
import { MediaLibrary } from '../helpers/MediaLibrary';
import { DashboardListener, MediaListener, SettingsListener, TelemetryListener, DataListener, PagesListener, ExtensionListener, SnippetListener, TaxonomyListener } from '../listeners/dashboard';
import { MediaListener as PanelMediaListener } from '../listeners/panel'
import { ModeListener } from '../listeners/general';
import {
DashboardListener,
MediaListener,
SettingsListener,
TelemetryListener,
DataListener,
PagesListener,
ExtensionListener,
SnippetListener,
TaxonomyListener,
LogListener,
LocalizationListener
} from '../listeners/dashboard';
import { MediaListener as PanelMediaListener } from '../listeners/panel';
import { GitListener, ModeListener } from '../listeners/general';
import { Folders } from './Folders';
export class Dashboard {
private static webview: WebviewPanel | null = null;
private static _viewData: DashboardData | undefined;
private static isDisposed: boolean = true;
private static isDisposed = true;
public static get viewData(): DashboardData | undefined {
return Dashboard._viewData;
@@ -34,15 +52,13 @@ export class Dashboard {
* Open or reveal the dashboard
*/
public static async open(data?: DashboardData) {
MediaLibrary.getInstance();
Dashboard._viewData = data;
if (Dashboard.isOpen) {
Dashboard.reveal(!!data);
} else {
Dashboard.create();
}
Dashboard.reveal(!!data);
} else {
Dashboard.create();
}
await commands.executeCommand('setContext', CONTEXT.isDashboardOpen, true);
}
@@ -57,12 +73,15 @@ export class Dashboard {
/**
* Reveal the dashboard if it is open
*/
public static reveal(hasData: boolean = false) {
public static reveal(hasData = false) {
if (Dashboard.webview) {
Dashboard.webview.reveal();
if (hasData) {
Dashboard.postWebviewMessage({ command: DashboardCommand.viewData, data: Dashboard.viewData });
Dashboard.postWebviewMessage({
command: DashboardCommand.viewData,
payload: Dashboard.viewData
});
}
}
}
@@ -74,7 +93,11 @@ export class Dashboard {
public static reload() {
if (Dashboard.isOpen) {
Dashboard.webview?.dispose();
Extension.getInstance().setState(ExtensionState.Dashboard.Pages.Cache, undefined, "workspace")
Extension.getInstance().setState(
ExtensionState.Dashboard.Pages.Cache,
undefined,
'workspace'
);
setTimeout(() => {
Dashboard.open();
@@ -85,7 +108,7 @@ export class Dashboard {
public static resetViewData() {
Dashboard._viewData = undefined;
}
/**
* Create the dashboard webview
*/
@@ -99,7 +122,8 @@ export class Dashboard {
ViewColumn.One,
{
enableScripts: true,
retainContextWhenHidden: true
retainContextWhenHidden: true,
enableCommandUris: true
}
);
@@ -110,14 +134,20 @@ export class Dashboard {
light: Uri.file(join(extensionUri.fsPath, 'assets/icons/frontmatter-short-light.svg'))
};
Dashboard.webview.webview.html = Dashboard.getWebviewContent(Dashboard.webview.webview, extensionUri);
Dashboard.webview.webview.html = Dashboard.getWebviewContent(
Dashboard.webview.webview,
extensionUri
);
Dashboard.webview.onDidChangeViewState(async () => {
if (!this.webview?.visible) {
Dashboard._viewData = undefined;
PanelMediaListener.getMediaSelection();
Dashboard.postWebviewMessage({ command: DashboardCommand.viewData, data: null });
Dashboard.postWebviewMessage({
command: DashboardCommand.viewData,
payload: null
});
}
await commands.executeCommand('setContext', CONTEXT.isDashboardOpen, this.webview?.visible);
@@ -130,13 +160,14 @@ export class Dashboard {
await commands.executeCommand('setContext', CONTEXT.isDashboardOpen, false);
});
SettingsHelper.onConfigChange((global?: any) => {
SettingsListener.getSettings();
SettingsHelper.onConfigChange(() => {
SettingsListener.getSettings(true);
});
Dashboard.webview.webview.onDidReceiveMessage(async (msg) => {
Logger.info(`Receiving message from webview: ${msg.command}`);
LocalizationListener.process(msg);
DashboardListener.process(msg);
ExtensionListener.process(msg);
MediaListener.process(msg);
@@ -146,7 +177,9 @@ export class Dashboard {
TelemetryListener.process(msg);
SnippetListener.process(msg);
ModeListener.process(msg);
GitListener.process(msg);
TaxonomyListener.process(msg);
LogListener.process(msg);
});
}
@@ -155,14 +188,17 @@ export class Dashboard {
* @returns The webview
*/
public static getWebview() {
if (Dashboard.isDisposed) {
return undefined;
}
return Dashboard.webview?.webview;
}
/**
* Post data to the dashboard
* @param msg
* @param msg
*/
public static postWebviewMessage(msg: { command: DashboardCommand, data?: any }) {
public static postWebviewMessage(msg: { command: DashboardCommand; payload?: unknown }) {
if (Dashboard.isDisposed) {
return;
}
@@ -171,22 +207,24 @@ export class Dashboard {
Dashboard.webview?.webview.postMessage(msg);
}
}
/**
* Retrieve the webview HTML contents
* @param webView
* @param webView
*/
private static getWebviewContent(webView: Webview, extensionPath: Uri): string {
const dashboardFile = "dashboardWebView.js";
const dashboardFile = 'dashboardWebView.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
let scriptUri = "";
let scriptUri = '';
const isProd = Extension.getInstance().isProductionMode;
if (isProd) {
scriptUri = webView.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile)).toString();
scriptUri = webView
.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile))
.toString();
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
}
const nonce = WebviewHelper.getNonce();
@@ -195,15 +233,51 @@ export class Dashboard {
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
// Get experimental setting
const experimental = SettingsHelper.get(SETTING_EXPERIMENTAL);
const extensibilityScripts = SettingsHelper.get<string[]>(SETTING_EXTENSIBILITY_SCRIPTS) || [];
const scriptsToLoad: string[] = [];
if (experimental) {
for (const script of extensibilityScripts) {
if (script.startsWith('https://')) {
scriptsToLoad.push(script);
} else {
const absScriptPath = Folders.getAbsFilePath(script);
const scriptUri = webView.asWebviewUri(Uri.file(absScriptPath));
scriptsToLoad.push(scriptUri.toString());
}
}
}
const csp = [
`default-src 'none';`,
`img-src ${`vscode-file://vscode-app`} ${webView.cspSource} https://api.visitorbadge.io 'self' 'unsafe-inline'`,
`script-src ${isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`} 'unsafe-eval'`,
`style-src ${webView.cspSource} 'self' 'unsafe-inline'`,
`img-src ${`vscode-file://vscode-app`} ${
webView.cspSource
} https://api.visitorbadge.io 'self' 'unsafe-inline' https://*`,
`media-src ${`vscode-file://vscode-app`} ${
webView.cspSource
} 'self' 'unsafe-inline' https://*`,
`script-src ${
isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`
} 'unsafe-eval' https://*`,
`style-src ${webView.cspSource} 'self' 'unsafe-inline' https://*`,
`font-src ${webView.cspSource}`,
`connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`}`
`connect-src https://o1022172.ingest.sentry.io https://* ${
isProd
? ``
: `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`
}`
];
const frontMatterUri = webView
.asWebviewUri(
SettingsHelper.projectConfigPath ? Uri.file(SettingsHelper.projectConfigPath) : Uri.file('')
)
.toString();
const webviewUrl = frontMatterUri.replace(`/${SettingsHelper.globalFile}`, '');
return `
<!DOCTYPE html>
<html lang="en" style="width:100%;height:100%;margin:0;padding:0;">
@@ -214,14 +288,26 @@ export class Dashboard {
<title>Front Matter Dashboard</title>
</head>
<body style="width:100%;height:100%;margin:0;padding:0;overflow:hidden" class="bg-gray-100 text-vulcan-500 dark:bg-vulcan-500 dark:text-whisper-500">
<div id="app" data-isProd="${isProd}" data-environment="${isBeta ? "BETA" : "main"}" data-version="${version.usedVersion}" style="width:100%;height:100%;margin:0;padding:0;" ${version.usedVersion ? "" : `data-showWelcome="true"`}></div>
<body style="width:100%;height:100%;margin:0;padding:0;overflow:hidden">
<div id="app" class="bg-gray-100 text-vulcan-500 dark:bg-vulcan-500 dark:text-whisper-500" data-isProd="${isProd}" data-environment="${
isBeta ? 'BETA' : 'main'
}" data-version="${version.usedVersion}" style="width:100%;height:100%;margin:0;padding:0;" ${
version.usedVersion ? '' : `data-showWelcome="true"`
} ${
experimental ? `data-experimental="${experimental}"` : ''
} data-webview-url="${webviewUrl}" ></div>
${(scriptsToLoad || [])
.map((script) => {
return `<script type="module" src="${script}" nonce="${nonce}"></script>`;
})
.join('')}
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`dashboard-${version.installedVersion}`}" alt="Daily usage" />
<script ${isProd ? `nonce="${nonce}"` : ""} src="${scriptUri}"></script>
</body>
</html>
`;
}
}
}

View File

@@ -1,12 +1,11 @@
import { Folders } from "./Folders";
import { ViewColumn, workspace } from "vscode";
import ContentProvider from "../providers/ContentProvider";
import { join } from "path";
import { ContentFolder } from "../models";
import { Folders } from './Folders';
import { ViewColumn, workspace } from 'vscode';
import ContentProvider from '../providers/ContentProvider';
import { join } from 'path';
import { ContentFolder } from '../models';
import { Settings } from '../helpers/SettingsHelper';
export class Diagnostics {
public static async show() {
const folders = Folders.get();
const projectName = Folders.getProjectFolderName();
@@ -25,11 +24,11 @@ ${projectName}
# Folders
${folders.map(f => `- ${f.title}: "${f.path}"`).join("\n")}
${folders.map((f) => `- ${f.title}: "${f.path}"`).join('\n')}
# Workspace folder
${wsFolder ? wsFolder.fsPath : "No workspace folder"}
${wsFolder ? wsFolder.fsPath : 'No workspace folder'}
# Total files
@@ -37,10 +36,16 @@ ${all}
# Folders to search files
${folderData.join("\n")}
${folderData.join('\n')}
# Complete frontmatter.json config
\`\`\`json
${JSON.stringify(Settings.globalConfig, null, 2)}
\`\`\`
`;
ContentProvider.show(logging, `${projectName} diagnostics`, "markdown", ViewColumn.One);
ContentProvider.show(logging, `${projectName} diagnostics`, 'markdown', ViewColumn.One);
}
private static async allProjectFiles() {
@@ -50,14 +55,26 @@ ${folderData.join("\n")}
private static async processFolder(folder: ContentFolder, projectName: string) {
let projectStart = folder.path.split(projectName).pop();
projectStart = projectStart || "";
projectStart = projectStart || '';
projectStart = projectStart?.replace(/\\/g, '/');
projectStart = projectStart?.startsWith('/') ? projectStart.substring(1) : projectStart;
const mdFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.md'));
const mdxFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.mdx'));
const markdownFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.markdown'));
const mdFiles = await workspace.findFiles(
join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.md')
);
const mdxFiles = await workspace.findFiles(
join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.mdx')
);
const markdownFiles = await workspace.findFiles(
join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.markdown')
);
return `- Project start length: ${projectStart.length} | Search in: "${join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.*')}" | mdFiles: ${mdFiles.length} | mdxFiles: ${mdxFiles.length} | markdownFiles: ${markdownFiles.length}`;
return `- Project start length: ${projectStart.length} | Search in: "${join(
projectStart,
folder.excludeSubdir ? '/' : '**/',
'*.*'
)}" | mdFiles: ${mdFiles.length} | mdxFiles: ${mdxFiles.length} | markdownFiles: ${
markdownFiles.length
}`;
}
}
}

View File

@@ -1,13 +1,20 @@
import { STATIC_FOLDER_PLACEHOLDER } from './../constants/StaticFolderPlaceholder';
import { Questions } from './../helpers/Questions';
import { SETTING_CONTENT_PAGE_FOLDERS, SETTING_CONTENT_STATIC_FOLDER, SETTING_CONTENT_SUPPORTED_FILETYPES, TelemetryEvent } from './../constants';
import { commands, Uri, workspace, window } from "vscode";
import { basename, dirname, join, relative, sep } from "path";
import { ContentFolder, FileInfo, FolderInfo } from "../models";
import uniqBy = require("lodash.uniqby");
import { Template } from "./Template";
import { Notifications } from "../helpers/Notifications";
import { Logger, Settings } from "../helpers";
import { existsSync, mkdirSync } from 'fs';
import {
SETTING_CONTENT_PAGE_FOLDERS,
SETTING_CONTENT_STATIC_FOLDER,
SETTING_CONTENT_SUPPORTED_FILETYPES,
SETTING_DATE_FORMAT,
TelemetryEvent
} from './../constants';
import { commands, Uri, workspace, window } from 'vscode';
import { basename, dirname, join, relative, sep } from 'path';
import { ContentFolder, FileInfo, FolderInfo, StaticFolder } from '../models';
import uniqBy = require('lodash.uniqby');
import { Template } from './Template';
import { Notifications } from '../helpers/Notifications';
import { Logger, processKnownPlaceholders, Settings } from '../helpers';
import { existsSync } from 'fs';
import { format } from 'date-fns';
import { Dashboard } from './Dashboard';
import { parseWinPath } from '../helpers/parseWinPath';
@@ -16,32 +23,41 @@ import { MediaListener, PagesListener, SettingsListener } from '../listeners/das
import { DEFAULT_FILE_TYPES } from '../constants/DefaultFileTypes';
import { Telemetry } from '../helpers/Telemetry';
import { glob } from 'glob';
import { mkdirAsync } from '../utils/mkdirAsync';
import { existsAsync } from '../utils';
export const WORKSPACE_PLACEHOLDER = `[[workspace]]`;
export class Folders {
/**
* Add a media folder
* @returns
* @returns
*/
public static async addMediaFolder(data?: {selectedFolder?: string}) {
let wsFolder = Folders.getWorkspaceFolder();
let staticFolder = Folders.getStaticFolderRelativePath();
public static async addMediaFolder(data?: { selectedFolder?: string }) {
const wsFolder = Folders.getWorkspaceFolder();
const staticFolder = Folders.getStaticFolderRelativePath();
let startPath = "";
let startPath = '';
if (data?.selectedFolder) {
startPath = data.selectedFolder.replace(parseWinPath(wsFolder?.fsPath || ""), "");
startPath = data.selectedFolder.replace(parseWinPath(wsFolder?.fsPath || ''), '');
} else if (staticFolder) {
startPath = `/${staticFolder}`;
}
if (startPath && !startPath.endsWith("/")) {
startPath += "/";
if (startPath && !startPath.endsWith('/')) {
startPath += '/';
}
const folderName = await window.showInputBox({
if (startPath.includes(STATIC_FOLDER_PLACEHOLDER.hexo.placeholder)) {
startPath = startPath.replace(
STATIC_FOLDER_PLACEHOLDER.hexo.placeholder,
STATIC_FOLDER_PLACEHOLDER.hexo.postsFolder
);
}
const folderName = await window.showInputBox({
title: `Add media folder`,
prompt: `Which name would you like to give to your folder (use "/" to create multi-level folders)?`,
value: startPath,
ignoreFocusOut: true,
@@ -52,23 +68,18 @@ export class Folders {
Notifications.warning(`No folder name was specified.`);
return;
}
const folders = folderName.split("/").filter(f => f);
let parentFolders: string[] = [];
for (const folder of folders) {
const folderPath = join(parseWinPath(wsFolder?.fsPath || ""), parentFolders.join("/"), folder);
await Folders.createFolder(join(parseWinPath(wsFolder?.fsPath || ''), folderName));
}
parentFolders.push(folder);
if (!existsSync(folderPath)) {
mkdirSync(folderPath);
}
public static async createFolder(folderPath: string) {
if (!(await existsAsync(folderPath))) {
await mkdirAsync(folderPath, { recursive: true });
}
if (Dashboard.isOpen) {
MediaHelpers.resetMedia();
MediaListener.sendMediaFiles(0, folderName);
MediaListener.sendMediaFiles(0, folderPath);
}
Telemetry.send(TelemetryEvent.addMediaFolder);
@@ -76,7 +87,7 @@ export class Folders {
/**
* Create content in a registered folder
* @returns
* @returns
*/
public static async create() {
const selectedFolder = await Questions.SelectContentFolder();
@@ -85,7 +96,7 @@ export class Folders {
}
const folders = Folders.get();
const location = folders.find(f => f.title === selectedFolder);
const location = folders.find((f) => f.title === selectedFolder);
if (location) {
const folderPath = Folders.getFolderPath(Uri.file(location.path));
if (folderPath) {
@@ -96,9 +107,9 @@ export class Folders {
/**
* Register the new folder path
* @param folder
* @param folderInfo
*/
public static async register(folderInfo: { title: string, path: Uri } | Uri) {
public static async register(folderInfo: { title: string; path: Uri } | Uri) {
let folderName = folderInfo instanceof Uri ? undefined : folderInfo.title;
const folder = folderInfo instanceof Uri ? folderInfo : folderInfo.path;
@@ -107,7 +118,9 @@ export class Folders {
let folders = Folders.get();
const exists = folders.find(f => f.path.includes(folder.fsPath) || f.path.includes(wslPath));
const exists = folders.find(
(f) => f.path.includes(folder.fsPath) || f.path.includes(wslPath)
);
if (exists) {
Notifications.warning(`Folder is already registered`);
@@ -115,7 +128,8 @@ export class Folders {
}
if (!folderName) {
folderName = await window.showInputBox({
folderName = await window.showInputBox({
title: `Register folder`,
prompt: `Which name would you like to specify for this folder?`,
placeHolder: `Folder name`,
value: basename(folder.fsPath),
@@ -128,63 +142,77 @@ export class Folders {
path: folder.fsPath
} as ContentFolder);
folders = uniqBy(folders, f => f.path);
folders = uniqBy(folders, (f) => f.path);
await Folders.update(folders);
Notifications.info(`Folder registered`);
Telemetry.send(TelemetryEvent.registerFolder);
Telemetry.send(TelemetryEvent.registerFolder);
SettingsListener.getSettings();
SettingsListener.getSettings(true);
}
}
/**
* Unregister a folder path
* @param folder
* @param folder
*/
public static async unregister(folder: Uri) {
if (folder && folder.path) {
let folders = Folders.get();
folders = folders.filter(f => f.path !== folder.fsPath);
folders = folders.filter((f) => f.path !== folder.fsPath);
await Folders.update(folders);
Telemetry.send(TelemetryEvent.unregisterFolder);
Telemetry.send(TelemetryEvent.unregisterFolder);
}
}
/**
* Get the static folder its relative path
* @returns
* @returns
*/
public static getStaticFolderRelativePath(): string | undefined {
let staticFolder = Settings.get<string>(SETTING_CONTENT_STATIC_FOLDER);
const staticFolder = Settings.get<string | StaticFolder>(SETTING_CONTENT_STATIC_FOLDER);
if (staticFolder && staticFolder.includes(WORKSPACE_PLACEHOLDER)) {
staticFolder = Folders.getAbsFilePath(staticFolder);
let assetFolder: string | undefined;
if (staticFolder && typeof staticFolder !== 'string' && staticFolder.path) {
assetFolder = staticFolder.path;
} else if (staticFolder && typeof staticFolder === 'string') {
assetFolder = staticFolder;
}
if (
assetFolder &&
(assetFolder.includes(WORKSPACE_PLACEHOLDER) || assetFolder === '/' || assetFolder === './')
) {
assetFolder =
assetFolder === '/' || assetFolder === './'
? Folders.getAbsFilePath(WORKSPACE_PLACEHOLDER)
: Folders.getAbsFilePath(assetFolder);
const wsFolder = Folders.getWorkspaceFolder();
if (wsFolder) {
const relativePath = relative(parseWinPath(wsFolder.fsPath), parseWinPath(staticFolder));
return relativePath;
const relativePath = relative(parseWinPath(wsFolder.fsPath), parseWinPath(assetFolder));
return relativePath === '' ? '/' : relativePath;
}
}
return staticFolder;
return assetFolder;
}
/**
* Retrieve the folder path
* @param folder
* @returns
* @param folder
* @returns
*/
public static getFolderPath(folder: Uri) {
let folderPath = "";
let folderPath = '';
const wsFolder = Folders.getWorkspaceFolder();
if (folder && folder.fsPath) {
folderPath = folder.fsPath;
} else if (wsFolder) {
folderPath = wsFolder.fsPath;
}
if (folder && folder.fsPath) {
folderPath = folder.fsPath;
} else if (wsFolder) {
folderPath = wsFolder.fsPath;
}
return folderPath;
}
@@ -193,12 +221,12 @@ export class Folders {
*/
public static getWorkspaceFolder(): Uri | undefined {
const folders = workspace.workspaceFolders;
if (folders && folders.length === 1) {
return folders[0].uri;
} else if (folders && folders.length > 1) {
let projectFolder = undefined;
let projectFolder = undefined;
for (const folder of folders) {
if (!projectFolder && existsSync(join(folder.uri.fsPath, Settings.globalFile))) {
projectFolder = folder.uri;
@@ -206,20 +234,22 @@ export class Folders {
}
if (!projectFolder) {
window.showWorkspaceFolderPick({
placeHolder: `Please select the main workspace folder for Front Matter to use.`
}).then(selectedFolder => {
if (selectedFolder) {
Settings.createGlobalFile(selectedFolder.uri);
// Full reload to make sure the whole extension is reloaded correctly
commands.executeCommand(`workbench.action.reloadWindow`);
}
});
window
.showWorkspaceFolderPick({
placeHolder: `Please select the main workspace folder for Front Matter to use.`
})
.then(async (selectedFolder) => {
if (selectedFolder) {
await Settings.createGlobalFile(selectedFolder.uri);
// Full reload to make sure the whole extension is reloaded correctly
commands.executeCommand(`workbench.action.reloadWindow`);
}
});
}
return projectFolder;
}
return undefined;
}
@@ -231,7 +261,7 @@ export class Folders {
if (wsFolder) {
return basename(wsFolder.fsPath);
}
return "";
return '';
}
/**
@@ -240,26 +270,37 @@ export class Folders {
public static async getInfo(limit?: number): Promise<FolderInfo[] | null> {
const supportedFiles = Settings.get<string[]>(SETTING_CONTENT_SUPPORTED_FILETYPES);
const folders = Folders.get();
const wsFolder = parseWinPath(Folders.getWorkspaceFolder()?.fsPath || '');
if (folders && folders.length > 0) {
let folderInfo: FolderInfo[] = [];
const folderInfo: FolderInfo[] = [];
for (const folder of folders) {
try {
const projectName = Folders.getProjectFolderName();
let projectStart = folder.path.split(projectName).pop();
if (projectStart) {
projectStart = projectStart.replace(/\\/g, '/');
projectStart = projectStart.startsWith('/') ? projectStart.substring(1) : projectStart;
const folderPath = parseWinPath(folder.path);
if (typeof folderPath === 'string') {
let files: Uri[] = [];
for (const fileType of (supportedFiles || DEFAULT_FILE_TYPES)) {
const filePath = join(projectStart, folder.excludeSubdir ? '/' : '**', `*${fileType.startsWith('.') ? '' : '.'}${fileType}`);
const foundFiles = await workspace.findFiles(filePath, '**/node_modules/**');
for (const fileType of supportedFiles || DEFAULT_FILE_TYPES) {
let filePath = join(
folderPath,
folder.excludeSubdir ? '/' : '**',
`*${fileType.startsWith('.') ? '' : '.'}${fileType}`
);
if (folderPath === '' && folder.excludeSubdir) {
filePath = `*${fileType.startsWith('.') ? '' : '.'}${fileType}`;
}
let foundFiles = await Folders.findFiles(filePath);
// Make sure these file are coming from the folder path (this could be an issue in multi-root workspaces)
foundFiles = foundFiles.filter((f) => parseWinPath(f.fsPath).startsWith(folderPath));
files = [...files, ...foundFiles];
}
if (files) {
let fileStats: FileInfo[] = [];
@@ -267,7 +308,7 @@ export class Folders {
try {
const fileName = basename(file.fsPath);
const folderName = dirname(file.fsPath).split(sep).pop();
const stats = await workspace.fs.stat(file);
fileStats.push({
@@ -282,7 +323,7 @@ export class Folders {
}
fileStats = fileStats.sort((a, b) => b.mtime - a.mtime);
if (limit) {
fileStats = fileStats.slice(0, limit);
}
@@ -307,48 +348,72 @@ export class Folders {
/**
* Get the folder settings
* @returns
* @returns
*/
public static get(): ContentFolder[] {
const wsFolder = Folders.getWorkspaceFolder();
const folders: ContentFolder[] = Settings.get(SETTING_CONTENT_PAGE_FOLDERS) as ContentFolder[];
const contentFolders = folders.map(folder => {
const contentFolders = folders.map((folder) => {
if (!folder.title) {
folder.title = basename(folder.path);
}
let folderPath = Folders.absWsFolder(folder, wsFolder);
if (!existsSync(folderPath)) {
Notifications.errorShowOnce(`Folder "${folder.title} (${folder.path})" does not exist. Please remove it from the settings.`, "Remove folder").then(answer => {
if (answer === "Remove folder") {
let folders = Folders.get();
Folders.update(folders.filter(f => f.path !== folder.path));
}
});
return null;
let folderPath: string | undefined = Folders.absWsFolder(folder, wsFolder);
if (folderPath.includes(`{{`) && folderPath.includes(`}}`)) {
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
folderPath = processKnownPlaceholders(folderPath, undefined, dateFormat);
} else {
if (folderPath && !existsSync(folderPath)) {
Notifications.errorShowOnce(
`Folder "${folder.title} (${folder.path})" does not exist. Please remove it from the settings.`,
'Remove folder',
'Create folder'
).then((answer) => {
if (answer === 'Remove folder') {
const folders = Folders.get();
Folders.update(folders.filter((f) => f.path !== folder.path));
} else if (answer === 'Create folder') {
mkdirAsync(folderPath as string, { recursive: true });
}
});
return null;
}
}
return {
...folder,
originalPath: folder.path,
path: folderPath
}
})
return contentFolders.filter(folder => folder !== null) as ContentFolder[];
};
});
return contentFolders.filter((folder) => folder !== null) as ContentFolder[];
}
/**
* Update the folder settings
* @param folders
* @param folders
*/
public static async update(folders: ContentFolder[]) {
const wsFolder = Folders.getWorkspaceFolder();
let folderDetails = folders.map(folder => ({
...folder,
path: Folders.relWsFolder(folder, wsFolder)
}));
const folderDetails = folders
.map((folder) => {
const detail = {
...folder,
path: Folders.relWsFolder(folder, wsFolder)
};
if (detail['$schema'] || detail.extended) {
return null;
}
delete detail.originalPath;
return detail;
})
.filter((folder) => folder !== null);
await Settings.update(SETTING_CONTENT_PAGE_FOLDERS, folderDetails, true);
@@ -358,39 +423,68 @@ export class Folders {
/**
* Retrieve the absolute file path
* @param filePath
* @returns
* @param filePath
* @returns
*/
public static getAbsFilePath(filePath: string): string {
const wsFolder = Folders.getWorkspaceFolder();
const isWindows = process.platform === 'win32';
let absPath = filePath.replace(WORKSPACE_PLACEHOLDER, parseWinPath(wsFolder?.fsPath || ""));
let absPath = filePath.replace(WORKSPACE_PLACEHOLDER, parseWinPath(wsFolder?.fsPath || ''));
absPath = isWindows ? absPath.split('/').join('\\') : absPath;
return absPath;
return parseWinPath(absPath);
}
/**
* Retrieve the absolute folder path
* @param filePath
* @returns
*/
public static getAbsFolderPath(folderPath: string): string {
const wsFolder = Folders.getWorkspaceFolder();
const isWindows = process.platform === 'win32';
let absPath = '';
if (folderPath.includes(WORKSPACE_PLACEHOLDER)) {
absPath = folderPath.replace(WORKSPACE_PLACEHOLDER, parseWinPath(wsFolder?.fsPath || ''));
} else {
absPath = join(parseWinPath(wsFolder?.fsPath || ''), folderPath);
}
absPath = isWindows ? absPath.split('/').join('\\') : absPath;
return parseWinPath(absPath);
}
/**
* Generate the absolute URL for the workspace
* @param folder
* @param wsFolder
* @returns
* @param folder
* @param wsFolder
* @returns
*/
private static absWsFolder(folder: ContentFolder, wsFolder?: Uri) {
const isWindows = process.platform === 'win32';
let absPath = folder.path.replace(WORKSPACE_PLACEHOLDER, parseWinPath(wsFolder?.fsPath || ""));
let absPath = folder.path.replace(WORKSPACE_PLACEHOLDER, parseWinPath(wsFolder?.fsPath || ''));
if (absPath.includes('../')) {
absPath = join(absPath);
}
absPath = isWindows ? absPath.split('/').join('\\') : absPath;
return absPath;
return parseWinPath(absPath);
}
/**
* Generate relative folder path
* @param folder
* @param wsFolder
* @returns
* @param folder
* @param wsFolder
* @returns
*/
public static relWsFolder(folder: ContentFolder, wsFolder?: Uri) {
const isWindows = process.platform === 'win32';
let absPath = parseWinPath(folder.path).replace(parseWinPath(wsFolder?.fsPath || ""), WORKSPACE_PLACEHOLDER);
let absPath = parseWinPath(folder.path).replace(
parseWinPath(wsFolder?.fsPath || ''),
WORKSPACE_PLACEHOLDER
);
absPath = isWindows ? absPath.split('\\').join('/') : absPath;
return absPath;
}
@@ -401,39 +495,109 @@ export class Folders {
public static async getContentFolders() {
// Find folders that contain files
const wsFolder = Folders.getWorkspaceFolder();
const supportedFiles = Settings.get<string[]>(SETTING_CONTENT_SUPPORTED_FILETYPES) || DEFAULT_FILE_TYPES;
const patterns = supportedFiles.map(fileType => `${join(parseWinPath(wsFolder?.fsPath || ""), "**", `*${fileType.startsWith('.') ? '' : '.'}${fileType}`)}`);
const supportedFiles =
Settings.get<string[]>(SETTING_CONTENT_SUPPORTED_FILETYPES) || DEFAULT_FILE_TYPES;
const patterns = supportedFiles.map(
(fileType) =>
`${join(
parseWinPath(wsFolder?.fsPath || ''),
'**',
`*${fileType.startsWith('.') ? '' : '.'}${fileType}`
)}`
);
let folders: string[] = [];
for (const pattern of patterns) {
try {
folders = [...folders, ...(await this.findFolders(pattern))];
} catch (e) {
Logger.error(`Something went wrong while searching for folders with pattern "${pattern}": ${(e as Error).message}`);
Logger.error(
`Something went wrong while searching for folders with pattern "${pattern}": ${
(e as Error).message
}`
);
}
}
// Filter out the workspace folder
if (wsFolder) {
folders = folders.filter(folder => folder !== wsFolder.fsPath);
folders = folders.filter((folder) => folder !== wsFolder.fsPath);
}
const uniqueFolders = [...new Set(folders)];
return uniqueFolders.map(folder => relative(wsFolder?.path || "", folder));
return uniqueFolders.map((folder) => relative(wsFolder?.path || '', folder));
}
/**
* Returns the file prefix for the given folder path
* @param folderPath
* @returns
*/
public static getFilePrefixByFolderPath(folderPath: string) {
const folders = Folders.get();
const pageFolder = folders.find((f) => parseWinPath(f.path) === parseWinPath(folderPath));
if (pageFolder && typeof pageFolder.filePrefix !== 'undefined') {
return pageFolder.filePrefix;
}
return;
}
/**
* Returns the file prefix for the given file path
* @param filePath
* @returns
*/
public static getFilePrefixBeFilePath(filePath: string) {
const folders = Folders.get();
if (folders.length > 0) {
filePath = parseWinPath(filePath);
let selectedFolder: ContentFolder | null = null;
for (const folder of folders) {
const folderPath = parseWinPath(folder.path);
if (filePath.startsWith(folderPath)) {
if (!selectedFolder || selectedFolder.path.length < folderPath.length) {
selectedFolder = folder;
}
}
}
if (selectedFolder && typeof selectedFolder.filePrefix !== 'undefined') {
return selectedFolder.filePrefix;
}
}
return;
}
/**
* Retrieve all content folders
* @param pattern
* @returns
* @param pattern
* @returns
*/
private static findFolders(pattern: string): Promise<string[]> {
return new Promise(resolve => {
glob(pattern, { ignore: "**/node_modules/**" }, (err, files) => {
const allFolders = files.map(file => dirname(file));
return new Promise((resolve) => {
glob(pattern, { ignore: '**/node_modules/**' }, (err, files) => {
const allFolders = files.map((file) => dirname(file));
const uniqueFolders = [...new Set(allFolders)];
resolve(uniqueFolders);
});
});
}
/**
* Find all files
* @param pattern
* @returns
*/
private static async findFiles(pattern: string): Promise<Uri[]> {
return new Promise((resolve) => {
glob(pattern, { ignore: '**/node_modules/**' }, (err, files) => {
const allFiles = files.map((file) => Uri.file(file));
resolve(allFiles);
});
});
}
}

View File

@@ -1,28 +1,41 @@
import { processFmPlaceholders } from './../helpers/processFmPlaceholders';
import { processPathPlaceholders } from './../helpers/processPathPlaceholders';
import { Telemetry } from './../helpers/Telemetry';
import { SETTING_PREVIEW_HOST, SETTING_PREVIEW_PATHNAME, CONTEXT, TelemetryEvent, PreviewCommands } from './../constants';
import {
SETTING_PREVIEW_HOST,
SETTING_PREVIEW_PATHNAME,
CONTEXT,
TelemetryEvent,
PreviewCommands,
SETTING_EXPERIMENTAL,
SETTING_DATE_FORMAT
} from './../constants';
import { ArticleHelper } from './../helpers/ArticleHelper';
import { join } from "path";
import { commands, env, Uri, ViewColumn, window } from "vscode";
import { Extension, parseWinPath, Settings } from '../helpers';
import { ContentFolder, PreviewSettings } from '../models';
import { join, parse } from 'path';
import { commands, env, Uri, ViewColumn, window, WebviewPanel } from 'vscode';
import { Extension, parseWinPath, processKnownPlaceholders, Settings } from '../helpers';
import { ContentFolder, ContentType, PreviewSettings } from '../models';
import { format } from 'date-fns';
import { DateHelper } from '../helpers/DateHelper';
import { Article } from '.';
import { urlJoin } from 'url-join-ts';
import { WebviewHelper } from '@estruyf/vscode';
import { Folders } from './Folders';
import { DataListener } from '../listeners/panel';
import { ParsedFrontMatter } from '../parsers';
export class Preview {
public static filePath: string | undefined = undefined;
public static webviews: { [filePath: string]: WebviewPanel } = {};
/** 
/**
* Init the preview
*/
public static async init() {
const settings = Preview.getSettings();
await commands.executeCommand('setContext', CONTEXT.canOpenPreview, !!settings.host);
}
/**
* Open the markdown preview in the editor
*/
@@ -32,59 +45,23 @@ export class Preview {
if (!settings.host) {
return;
}
const editor = window.activeTextEditor;
const crntFilePath = editor?.document.uri.fsPath;
this.filePath = crntFilePath;
if (crntFilePath && this.webviews[crntFilePath]) {
this.webviews[crntFilePath].reveal();
return;
}
const article = editor ? ArticleHelper.getFrontMatter(editor) : null;
let slug = article?.data ? article.data.slug : "";
let pathname = settings.pathname;
// Check if there is a pathname defined on content folder level
const folders = Folders.get();
if (folders.length > 0) {
const foldersWithPath = folders.filter(folder => folder.previewPath);
const filePath = parseWinPath(editor?.document.uri.fsPath);
let selectedFolder: ContentFolder | null = null;
for (const folder of foldersWithPath) {
if (filePath.startsWith(folder.path)) {
if (!selectedFolder || selectedFolder.path.length < folder.path.length) {
selectedFolder = folder;
}
}
}
if (selectedFolder) {
pathname = selectedFolder.previewPath;
}
}
// Check if there is a pathname defined on content type level
if (article?.data) {
const contentType = ArticleHelper.getContentType(article.data);
if (contentType && contentType.previewPath) {
pathname = contentType.previewPath;
}
}
if (!slug) {
slug = Article.getSlug();
}
if (pathname) {
const articleDate = ArticleHelper.getDate(article);
try {
slug = join(format(articleDate || new Date(), DateHelper.formatUpdate(pathname) as string), slug);
} catch (error) {
slug = join(pathname, slug);
}
}
const slug = await this.getContentSlug(article, editor?.document.uri.fsPath);
// Create the preview webview
const webView = window.createWebviewPanel(
'frontMatterPreview',
'FrontMatter Preview',
article?.data?.title ? `Preview: ${article?.data?.title}` : 'FrontMatter Preview',
{
viewColumn: ViewColumn.Beside,
preserveFocus: true
@@ -94,18 +71,39 @@ export class Preview {
}
);
if (crntFilePath) {
this.webviews[crntFilePath] = webView;
}
webView.iconPath = {
dark: Uri.file(join(extensionPath, 'assets/icons/frontmatter-short-dark.svg')),
light: Uri.file(join(extensionPath, 'assets/icons/frontmatter-short-light.svg'))
}
};
const localhostUrl = await env.asExternalUri(
Uri.parse(settings.host)
);
const localhostUrl = await this.getLocalServerUrl();
const cspSource = webView.webview.cspSource;
webView.webview.onDidReceiveMessage(message => {
webView.onDidDispose(() => {
this.filePath = undefined;
if (crntFilePath) {
delete this.webviews[crntFilePath];
}
webView.dispose();
});
webView.onDidChangeViewState(async (e) => {
if (e.webviewPanel.visible) {
this.filePath = crntFilePath;
if (crntFilePath) {
const article = await ArticleHelper.getFrontMatterByPath(crntFilePath);
DataListener.pushMetadata(article?.data);
}
}
});
webView.webview.onDidReceiveMessage((message) => {
switch (message.command) {
case PreviewCommands.toVSCode.open:
if (message.data) {
@@ -115,8 +113,7 @@ export class Preview {
}
});
const dashboardFile = "dashboardWebView.js";
const dashboardFile = 'dashboardWebView.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
@@ -127,23 +124,34 @@ export class Preview {
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
const extensionUri = ext.extensionPath;
const csp = [
`default-src 'none';`,
`img-src ${localhostUrl} ${cspSource} http: https:;`,
`script-src ${isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`} 'unsafe-eval'`,
`script-src ${
isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`
} 'unsafe-eval'`,
`style-src ${cspSource} 'self' 'unsafe-inline' http: https:`,
`connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`}`,
`frame-src ${localhostUrl} ${cspSource} http: https:;`,
`connect-src https://o1022172.ingest.sentry.io ${
isProd
? ``
: `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`
}`,
`frame-src ${localhostUrl} ${cspSource} http: https:;`
];
let scriptUri = "";
let scriptUri = '';
if (isProd) {
scriptUri = webView.webview.asWebviewUri(Uri.joinPath(extensionUri, 'dist', dashboardFile)).toString();
scriptUri = webView.webview
.asWebviewUri(Uri.joinPath(extensionUri, 'dist', dashboardFile))
.toString();
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
}
// Get experimental setting
const experimental = Settings.get(SETTING_EXPERIMENTAL);
webView.webview.html = `
<!DOCTYPE html>
<html lang="en" style="width:100%;height:100%;margin:0;padding:0;">
@@ -155,9 +163,16 @@ export class Preview {
<title>Front Matter Preview</title>
</head>
<body style="width:100%;height:100%;margin:0;padding:0;overflow:hidden">
<div id="app" data-type="preview" data-url="${urlJoin(localhostUrl.toString(), slug || '')}" data-isProd="${isProd}" data-environment="${isBeta ? "BETA" : "main"}" data-version="${version.usedVersion}" style="width:100%;height:100%;margin:0;padding:0;"></div>
<div id="app" data-type="preview" data-url="${urlJoin(
localhostUrl.toString(),
slug || ''
)}" data-isProd="${isProd}" data-environment="${
isBeta ? 'BETA' : 'main'
}" data-version="${version.usedVersion}" ${
experimental ? `data-experimental="${experimental}"` : ''
} style="width:100%;height:100%;margin:0;padding:0;"></div>
<script ${isProd ? `nonce="${nonce}"` : ""} src="${scriptUri}"></script>
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
</body>
</html>
`;
@@ -165,6 +180,159 @@ export class Preview {
Telemetry.send(TelemetryEvent.openPreview);
}
/**
* Update the url of the preview webview
* @param filePath
* @param slug
*/
public static async updatePageUrl(filePath: string, slug?: string) {
const webView = this.webviews[filePath];
if (webView) {
const localhost = await this.getLocalServerUrl();
const article = await ArticleHelper.getFrontMatterByPath(filePath);
const slug = await this.getContentSlug(article, filePath);
webView.webview.postMessage({
command: PreviewCommands.toWebview.updateUrl,
payload: urlJoin(localhost.toString(), slug || '')
});
}
}
/**
* Retrieve the slug of the content
* @param article
* @param filePath
* @returns
*/
private static async getContentSlug(
article: ParsedFrontMatter | null,
filePath?: string
): Promise<string | undefined> {
if (!filePath) {
return;
}
let slug = article?.data ? article.data.slug : '';
const settings = this.getSettings();
let pathname = settings.pathname;
let selectedFolder: ContentFolder | undefined | null = null;
filePath = parseWinPath(filePath);
let contentType: ContentType | undefined = undefined;
if (article?.data) {
contentType = ArticleHelper.getContentType(article.data);
}
// Check if there is a pathname defined on content folder level
const folders = Folders.get();
if (folders.length > 0) {
const foldersWithPath = folders.filter((folder) => folder.previewPath);
for (const folder of foldersWithPath) {
const folderPath = parseWinPath(folder.path);
if (filePath.startsWith(folderPath)) {
if (!selectedFolder || selectedFolder.path.length < folderPath.length) {
selectedFolder = folder;
}
}
}
if (!selectedFolder && article?.data && contentType && !contentType.previewPath) {
// Try to find the folder by content type
const crntFolders = folders.filter((folder) =>
folder.contentTypes?.includes((contentType as ContentType).name)
);
if (crntFolders && crntFolders.length === 1) {
selectedFolder = crntFolders[0];
} else if (crntFolders && crntFolders.length > 1) {
selectedFolder = await Preview.askUserToPickFolder(crntFolders);
} else {
selectedFolder = await Preview.askUserToPickFolder(folders.filter((f) => f.previewPath));
}
}
if (selectedFolder && selectedFolder.previewPath) {
pathname = selectedFolder.previewPath;
}
}
// Check if there is a pathname defined on content type level
if (article?.data) {
if (contentType && contentType.previewPath) {
pathname = contentType.previewPath;
}
}
if (!slug) {
slug = Article.getSlug();
}
if (pathname) {
// Known placeholders
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
pathname = processKnownPlaceholders(pathname, article?.data?.title, dateFormat);
// Custom placeholders
pathname = await ArticleHelper.processCustomPlaceholders(
pathname,
article?.data?.title,
filePath
);
// Process the path placeholders - {{pathToken.<integer>}}
if (filePath) {
const wsFolder = Folders.getWorkspaceFolder();
// Get relative file path
const folderPath = wsFolder ? parseWinPath(wsFolder.fsPath) : '';
const relativePath = filePath.replace(folderPath, '');
pathname = processPathPlaceholders(pathname, relativePath, filePath, selectedFolder);
const file = parse(filePath);
if (file.name.toLowerCase() === 'index' && pathname.endsWith(slug)) {
slug = '';
}
}
// Support front matter placeholders - {{fm.<field>}}
pathname = processFmPlaceholders(pathname, article?.data);
try {
const articleDate = ArticleHelper.getDate(article);
slug = join(
format(articleDate || new Date(), DateHelper.formatUpdate(pathname) as string),
slug
);
} catch (error) {
slug = join(pathname, slug);
}
}
// Make sure there are no backslashes in the slug
slug = parseWinPath(slug);
// Verify if the slug doesn't end with _index or index
if (slug.endsWith('_index') || slug.endsWith('index')) {
slug = slug.substring(0, slug.endsWith('_index') ? slug.length - 6 : slug.length - 5);
}
return slug;
}
/**
* Retrieve the localhost url
* @returns
*/
private static async getLocalServerUrl() {
const settings = Preview.getSettings();
const crntUrl = settings?.host?.startsWith('http') ? settings.host : `http://${settings.host}`;
const localhostUrl = await env.asExternalUri(Uri.parse(crntUrl));
return localhostUrl;
}
/**
* Retrieve all settings related to the preview command
*/
@@ -177,4 +345,32 @@ export class Preview {
pathname
};
}
/**
* Ask the user to select the folder of the article to preview
* @param crntFolders
* @returns
*/
private static async askUserToPickFolder(
crntFolders: ContentFolder[]
): Promise<ContentFolder | undefined> {
let selectedFolder: ContentFolder | undefined = undefined;
if (crntFolders.length === 0) {
return undefined;
}
// Ask the user to select the folder
const folderNames = crntFolders.map((folder) => folder.title);
const selectedFolderName = await window.showQuickPick(folderNames, {
canPickMany: false,
title: 'Select the folder of the article to preview'
});
if (selectedFolderName) {
selectedFolder = crntFolders.find((folder) => folder.title === selectedFolderName);
}
return selectedFolder;
}
}

View File

@@ -1,22 +1,33 @@
import { DEFAULT_CONTENT_TYPE } from './../constants/ContentType';
import { Telemetry } from './../helpers/Telemetry';
import { workspace, Uri } from "vscode";
import { join } from "path";
import * as fs from "fs";
import { Notifications } from "../helpers/Notifications";
import { Template } from "./Template";
import { Folders } from "./Folders";
import { FrameworkDetector, Logger, Settings } from "../helpers";
import { SETTING_CONTENT_DEFAULT_FILETYPE, SETTING_TAXONOMY_CONTENT_TYPES, TelemetryEvent } from "../constants";
import { workspace, Uri, commands, window } from 'vscode';
import { join } from 'path';
import { Notifications } from '../helpers/Notifications';
import { Template } from './Template';
import { Folders } from './Folders';
import {
Extension,
FrameworkDetector,
Logger,
MediaLibrary,
Settings,
TaxonomyHelper
} from '../helpers';
import {
COMMAND_NAME,
SETTING_CONTENT_DEFAULT_FILETYPE,
SETTING_TAXONOMY_CONTENT_TYPES,
TelemetryEvent
} from '../constants';
import { SettingsListener } from '../listeners/dashboard';
import { existsAsync, writeFileAsync } from '../utils';
export class Project {
private static content = `---
title:
slug:
description:
author:
author:
date: 2019-08-22T15:20:28.000Z
lastmod: 2019-08-22T15:20:28.000Z
draft: true
@@ -25,8 +36,21 @@ categories: []
---
`;
public static registerCommands() {
const ext = Extension.getInstance();
const subscriptions = ext.subscriptions;
subscriptions.push(commands.registerCommand(COMMAND_NAME.switchProject, Project.switchProject));
}
public static isInitialized() {
return Settings.hasProjectFile();
const hasProjectFile = Settings.hasProjectFile();
// If it has a project file, initialize the media library
if (hasProjectFile) {
MediaLibrary.getInstance();
TaxonomyHelper.initDb();
}
return hasProjectFile;
}
/**
@@ -34,38 +58,63 @@ categories: []
*/
public static async init(sampleTemplate?: boolean) {
try {
Settings.createTeamSettings();
await Settings.createTeamSettings();
// Add the default content type
Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, [DEFAULT_CONTENT_TYPE], true);
await Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, [DEFAULT_CONTENT_TYPE], true);
if (sampleTemplate !== undefined) {
await Project.createSampleTemplate();
} else {
Notifications.info("Project initialized successfully.");
Notifications.info('Project initialized successfully.');
}
// Initialize the media library
MediaLibrary.getInstance();
// Initialize the taxonomy database
TaxonomyHelper.initDb();
Telemetry.send(TelemetryEvent.initialization);
// Check if you can find the framework
const wsFolder = Folders.getWorkspaceFolder();
const framework = FrameworkDetector.get(wsFolder?.fsPath || "");
const framework = await FrameworkDetector.get(wsFolder?.fsPath || '');
if (framework) {
SettingsListener.setFramework(framework.name);
await SettingsListener.setFramework(framework.name);
}
SettingsListener.getSettings();
} catch (err: any) {
SettingsListener.getSettings(true);
} catch (error: unknown) {
const err = error as Error;
Logger.error(`Project::init: ${err?.message || err}`);
Notifications.error(`Sorry, something went wrong - ${err?.message || err}`);
}
}
public static async switchProject() {
const projects = Settings.getProjects();
const project = await window.showQuickPick(
projects.map((p) => p.name),
{
canPickMany: false,
ignoreFocusOut: true,
title: 'Select a project to switch to'
}
);
if (!project) {
return;
}
SettingsListener.switchProject(project);
}
/**
* Creates the templates folder + sample if needed
* @param sampleTemplate
* @returns
* @param sampleTemplate
* @returns
*/
public static async createSampleTemplate(sampleTemplate?: boolean) {
const fileType = Settings.get<string>(SETTING_CONTENT_DEFAULT_FILETYPE);
@@ -76,16 +125,18 @@ categories: []
if (!folder || !templatePath) {
return;
}
const article = Uri.file(join(templatePath.fsPath, `article.${fileType}`));
if (!fs.existsSync(templatePath.fsPath)) {
if (!(await existsAsync(templatePath.fsPath))) {
await workspace.fs.createDirectory(templatePath);
}
if (sampleTemplate) {
fs.writeFileSync(article.fsPath, Project.content, { encoding: "utf-8" });
Notifications.info("Sample template created.");
await writeFileAsync(article.fsPath, Project.content, {
encoding: 'utf-8'
});
Notifications.info('Sample template created.');
}
}
@@ -103,4 +154,4 @@ categories: []
const templatePath = Uri.file(join(wsFolder.fsPath, folder));
return templatePath;
}
}
}

View File

@@ -1,48 +1,49 @@
import { TaxonomyHelper } from './../helpers/TaxonomyHelper';
import * as vscode from 'vscode';
import { TaxonomyType } from "../models";
import { SETTING_TAXONOMY_TAGS, SETTING_TAXONOMY_CATEGORIES, EXTENSION_NAME } from '../constants';
import { ArticleHelper, Settings as SettingsHelper, FilesHelper } from '../helpers';
import { TaxonomyType } from '../models';
import { EXTENSION_NAME } from '../constants';
import { ArticleHelper, FilesHelper } from '../helpers';
import { FrontMatterParser } from '../parsers';
import { Notifications } from '../helpers/Notifications';
export class Settings {
/**
* Create a new taxonomy
*
* @param type
*
* @param type
*/
public static async create(type: TaxonomyType) {
const newOption = await vscode.window.showInputBox({
prompt: `Insert the value of the ${type === TaxonomyType.Tag ? "tag" : "category"} that you want to add to your configuration.`,
placeHolder: `Name of the ${type === TaxonomyType.Tag ? "tag" : "category"}`,
const newOption = await vscode.window.showInputBox({
prompt: `Insert the value of the ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} that you want to add to your configuration.`,
placeHolder: `Name of the ${type === TaxonomyType.Tag ? 'tag' : 'category'}`,
ignoreFocusOut: true
});
if (newOption) {
const configSetting = type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES;
let options = SettingsHelper.get(configSetting, true) as string[];
if (!options) {
options = [];
}
if (options.find(o => o === newOption)) {
Notifications.info(`The provided ${type === TaxonomyType.Tag ? "tag" : "category"} already exists.`);
if (newOption) {
let options = (await TaxonomyHelper.get(type)) || [];
if (options.find((o) => o === newOption)) {
Notifications.info(
`The provided ${type === TaxonomyType.Tag ? 'tag' : 'category'} already exists.`
);
return;
}
options.push(newOption);
await SettingsHelper.updateTaxonomy(type, options);
TaxonomyHelper.update(type, options);
// Ask if the new term needs to be added to the page
const addToPage = await vscode.window.showQuickPick(["yes", "no"], {
canPickMany: false,
placeHolder: `Do you want to add the new ${type === TaxonomyType.Tag ? "tag" : "category"} to the page?`,
const addToPage = await vscode.window.showQuickPick(['yes', 'no'], {
canPickMany: false,
placeHolder: `Do you want to add the new ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} to the page?`,
ignoreFocusOut: true
});
if (addToPage && addToPage === "yes") {
if (addToPage && addToPage === 'yes') {
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
@@ -53,11 +54,11 @@ export class Settings {
return;
}
const matterProp: string = type === TaxonomyType.Tag ? "tags" : "categories";
const matterProp: string = type === TaxonomyType.Tag ? 'tags' : 'categories';
// Add the selected options to the options array
if (article.data[matterProp]) {
const propData: string[] = article.data[matterProp];
if (propData && !propData.find(o => o === newOption)) {
if (propData && !propData.find((o) => o === newOption)) {
propData.push(newOption);
}
} else {
@@ -69,7 +70,6 @@ export class Settings {
}
}
/**
* Export the tags/categories front matter to the user settings
*/
@@ -80,78 +80,84 @@ export class Settings {
return;
}
vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: `${EXTENSION_NAME}: exporting tags and categories`,
cancellable: false
}, async (progress) => {
// Fetching all tags and categories from MD files
let tags: string[] = [];
let categories: string[] = [];
vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: `${EXTENSION_NAME}: exporting tags and categories`,
cancellable: false
},
async (progress) => {
// Fetching all tags and categories from MD files
let tags: string[] = [];
let categories: string[] = [];
// Set the initial progress
const progressNr = allMdFiles.length/100;
progress.report({ increment: 0});
// Set the initial progress
const progressNr = allMdFiles.length / 100;
progress.report({ increment: 0 });
let i = 0;
for (const file of allMdFiles) {
progress.report({ increment: (++i/progressNr) });
const mdFile = await vscode.workspace.openTextDocument(file);
if (mdFile) {
const txtData = mdFile.getText();
if (txtData) {
try {
const article = FrontMatterParser.fromFile(txtData);
if (article && article.data) {
const { data } = article;
const mdTags = data["tags"];
const mdCategories = data["categories"];
if (mdTags) {
tags = [...tags, ...mdTags];
let i = 0;
for (const file of allMdFiles) {
progress.report({ increment: ++i / progressNr });
const mdFile = await vscode.workspace.openTextDocument(file);
if (mdFile) {
const txtData = mdFile.getText();
if (txtData) {
try {
const article = FrontMatterParser.fromFile(txtData);
if (article && article.data) {
const { data } = article;
const mdTags = data['tags'];
const mdCategories = data['categories'];
if (mdTags) {
tags = [...tags, ...mdTags];
}
if (mdCategories) {
categories = [...categories, ...mdCategories];
}
}
if (mdCategories) {
categories = [...categories, ...mdCategories];
}
}
} catch (e) {
// Continue with the next file
} catch (e) {
// Continue with the next file
}
}
}
}
// Retrieve the currently known tags, and add the new ones
let crntTags: string[] = (await TaxonomyHelper.get(TaxonomyType.Tag)) || [];
if (!crntTags) {
crntTags = [];
}
crntTags = [...crntTags, ...tags];
// Update the tags and filter out the duplicates
crntTags = [...new Set(crntTags)];
crntTags = crntTags.sort().filter((t) => !!t);
TaxonomyHelper.update(TaxonomyType.Tag, crntTags);
// Retrieve the currently known tags, and add the new ones
let crntCategories: string[] = (await TaxonomyHelper.get(TaxonomyType.Category)) || [];
if (!crntCategories) {
crntCategories = [];
}
crntCategories = [...crntCategories, ...categories];
// Update the categories and filter out the duplicates
crntCategories = [...new Set(crntCategories)];
crntCategories = crntCategories.sort().filter((c) => !!c);
TaxonomyHelper.update(TaxonomyType.Category, crntCategories);
// Done
Notifications.info(
`Export completed. Tags: ${crntTags.length} - Categories: ${crntCategories.length}.`
);
}
// Retrieve the currently known tags, and add the new ones
let crntTags: string[] = SettingsHelper.get(SETTING_TAXONOMY_TAGS, true) as string[];
if (!crntTags) { crntTags = []; }
crntTags = [...crntTags, ...tags];
// Update the tags and filter out the duplicates
crntTags = [...new Set(crntTags)];
crntTags = crntTags.sort().filter(t => !!t);
await SettingsHelper.update(SETTING_TAXONOMY_TAGS, crntTags, true);
// Retrieve the currently known tags, and add the new ones
let crntCategories: string[] = SettingsHelper.get(SETTING_TAXONOMY_CATEGORIES, true) as string[];
if (!crntCategories) { crntCategories = []; }
crntCategories = [...crntCategories, ...categories];
// Update the categories and filter out the duplicates
crntCategories = [...new Set(crntCategories)];
crntCategories = crntCategories.sort().filter(c => !!c);
await SettingsHelper.update(SETTING_TAXONOMY_CATEGORIES, crntCategories, true);
// Done
Notifications.info(`Export completed. Tags: ${crntTags.length} - Categories: ${crntCategories.length}.`);
});
);
}
/**
* Remap a tag or category to a new one
*/
public static async remap() {
const taxType = await vscode.window.showQuickPick([
"Tag",
"Category"
], {
const taxType = await vscode.window.showQuickPick(['Tag', 'Category'], {
title: `Remap`,
placeHolder: `What do you want to remap?`,
canPickMany: false,
ignoreFocusOut: true
@@ -161,16 +167,16 @@ export class Settings {
return;
}
const type = taxType === "Tag" ? TaxonomyType.Tag : TaxonomyType.Category;
let options = SettingsHelper.getTaxonomy(type);
const type = taxType === 'Tag' ? TaxonomyType.Tag : TaxonomyType.Category;
const options = (await TaxonomyHelper.get(type)) || [];
if (!options || options.length === 0) {
Notifications.info(`No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`);
Notifications.info(`No ${type === TaxonomyType.Tag ? 'tags' : 'categories'} configured.`);
return;
}
const selectedOption = await vscode.window.showQuickPick(options, {
placeHolder: `Select your ${type === TaxonomyType.Tag ? "tags" : "categories"} to insert`,
const selectedOption = await vscode.window.showQuickPick(options, {
placeHolder: `Select your ${type === TaxonomyType.Tag ? 'tags' : 'categories'} to insert`,
canPickMany: false,
ignoreFocusOut: true
});
@@ -179,27 +185,31 @@ export class Settings {
return;
}
const newOptionValue = await vscode.window.showInputBox({
prompt: `Specify the value of the ${type === TaxonomyType.Tag ? "tag" : "category"} with which you want to remap "${selectedOption}". Leave the input <blank> if you want to remove the ${type === TaxonomyType.Tag ? "tag" : "category"} from all articles.`,
placeHolder: `Name of the ${type === TaxonomyType.Tag ? "tag" : "category"}`,
const newOptionValue = await vscode.window.showInputBox({
prompt: `Specify the value of the ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} with which you want to remap "${selectedOption}". Leave the input <blank> if you want to remove the ${
type === TaxonomyType.Tag ? 'tag' : 'category'
} from all articles.`,
placeHolder: `Name of the ${type === TaxonomyType.Tag ? 'tag' : 'category'}`,
ignoreFocusOut: true
});
if (!newOptionValue) {
const deleteAnswer = await vscode.window.showQuickPick(["yes", "no"], {
canPickMany: false,
placeHolder: `Delete ${selectedOption} ${type === TaxonomyType.Tag ? "tag" : "category"}?`,
const deleteAnswer = await vscode.window.showQuickPick(['yes', 'no'], {
canPickMany: false,
placeHolder: `Delete ${selectedOption} ${type === TaxonomyType.Tag ? 'tag' : 'category'}?`,
ignoreFocusOut: true
});
if (deleteAnswer === "no") {
if (deleteAnswer === 'no') {
return;
}
}
if (newOptionValue) {
TaxonomyHelper.process("edit", type, selectedOption, newOptionValue);
TaxonomyHelper.process('edit', type, selectedOption, newOptionValue);
} else {
TaxonomyHelper.process("delete", type, selectedOption, undefined);
TaxonomyHelper.process('delete', type, selectedOption, undefined);
}
}
}
}

View File

@@ -1,68 +1,99 @@
import { CONTEXT, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH } from './../constants';
import { ParsedFrontMatter } from './../parsers/FrontMatterParser';
import {
CONTEXT,
NOTIFICATION_TYPE,
SETTING_SEO_DESCRIPTION_FIELD,
SETTING_SEO_DESCRIPTION_LENGTH,
SETTING_SEO_TITLE_FIELD,
SETTING_SEO_TITLE_LENGTH
} from './../constants';
import * as vscode from 'vscode';
import { ArticleHelper, SeoHelper, Settings } from '../helpers';
import { ExplorerView } from '../explorerView/ExplorerView';
import { ArticleHelper, Notifications, SeoHelper, Settings } from '../helpers';
import { PanelProvider } from '../panelWebView/PanelProvider';
import { DefaultFields } from '../constants';
import { ContentType } from '../helpers/ContentType';
import { DataListener } from '../listeners/panel';
import { commands } from 'vscode';
import { Field } from '../models';
import { Preview } from './Preview';
export class StatusListener {
/**
* Update the text of the status bar
*
* @param frontMatterSB
* @param collection
*
* @param frontMatterSB
* @param collection
*/
public static async verify(frontMatterSB: vscode.StatusBarItem, collection: vscode.DiagnosticCollection) {
const draftMsg = "in draft";
const publishMsg = "to publish";
public static async verify(
frontMatterSB: vscode.StatusBarItem,
collection: vscode.DiagnosticCollection
) {
const draftMsg = 'in draft';
const publishMsg = 'to publish';
const draft = ContentType.getDraftField();
if (!draft || draft.type !== "boolean") {
if (!draft || draft.type !== 'boolean') {
frontMatterSB.hide();
}
let editor = vscode.window.activeTextEditor;
if (editor && ArticleHelper.isSupportedFile()) {
const editor = vscode.window.activeTextEditor;
let document = editor?.document;
if (!document) {
const filePath = Preview.filePath;
if (filePath) {
document = await vscode.workspace.openTextDocument(vscode.Uri.file(filePath));
}
}
if (document && ArticleHelper.isSupportedFile(document)) {
try {
commands.executeCommand('setContext', CONTEXT.isValidFile, true);
const article = ArticleHelper.getFrontMatter(editor);
const article = editor
? ArticleHelper.getFrontMatter(editor)
: await ArticleHelper.getFrontMatterByPath(document.uri.fsPath);
// Update the StatusBar based on the article draft state
if (article && typeof article.data["draft"] !== "undefined") {
if (article.data["draft"] === true) {
if (article && typeof article.data['draft'] !== 'undefined') {
if (article.data['draft'] === true) {
frontMatterSB.text = `$(book) ${draftMsg}`;
frontMatterSB.show();
} else if (article.data["draft"] === false) {
} else if (article.data['draft'] === false) {
frontMatterSB.text = `$(book) ${publishMsg}`;
frontMatterSB.show();
}
}
// Check SEO for title and description length
// Check SEO and required fields
if (article && article.data) {
collection.clear();
// Retrieve the SEO config properties
const titleLength = Settings.get(SETTING_SEO_TITLE_LENGTH) as number || -1;
const descLength = Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) as number || -1;
const fieldName = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
if (article.data.title && titleLength > -1) {
SeoHelper.checkLength(editor, collection, article, "title", titleLength);
const titleLength = (Settings.get(SETTING_SEO_TITLE_LENGTH) as number) || -1;
const descLength = (Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) as number) || -1;
const titleField =
(Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title;
const descriptionField =
(Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string) || DefaultFields.Description;
if (editor && article.data[titleField] && titleLength > -1) {
SeoHelper.checkLength(editor, collection, article, titleField, titleLength);
}
if (article.data[fieldName] && descLength > -1) {
SeoHelper.checkLength(editor, collection, article, fieldName, descLength);
if (editor && article.data[descriptionField] && descLength > -1) {
SeoHelper.checkLength(editor, collection, article, descriptionField, descLength);
}
// Check the required fields
if (editor) {
StatusListener.verifyRequiredFields(editor, article, collection);
}
}
const panel = ExplorerView.getInstance();
const panel = PanelProvider.getInstance();
if (panel && panel.visible) {
DataListener.pushMetadata(article!.data);
DataListener.pushMetadata(article?.data);
}
return;
@@ -72,7 +103,7 @@ export class StatusListener {
} else {
commands.executeCommand('setContext', CONTEXT.isValidFile, false);
const panel = ExplorerView.getInstance();
const panel = PanelProvider.getInstance();
if (panel && panel.visible) {
DataListener.pushMetadata(null);
}
@@ -80,4 +111,114 @@ export class StatusListener {
frontMatterSB.hide();
}
}
/**
* Verify the required fields
* @param article
* @param collection
*/
private static verifyRequiredFields(
editor: vscode.TextEditor,
article: ParsedFrontMatter,
collection: vscode.DiagnosticCollection
) {
// Check for missing fields
const emptyFields = ContentType.findEmptyRequiredFields(article);
const fieldsToReport = [];
if (emptyFields && emptyFields.length > 0) {
const text = editor.document.getText();
const markdown = ArticleHelper.stringifyFrontMatter('', article.data);
const editorSpaces = vscode.window.activeTextEditor?.options?.tabSize;
const requiredDiagnostics: vscode.Diagnostic[] = [];
for (const fields of emptyFields) {
let txtIdx = -1;
let fieldName = '';
let level = 0;
for (const field of fields) {
const totalSpaces =
level * (typeof editorSpaces === 'string' ? parseInt(editorSpaces) : editorSpaces || 2);
const crntIdx = StatusListener.findFieldLine(text, txtIdx, totalSpaces, field);
if (crntIdx && crntIdx > txtIdx) {
txtIdx = crntIdx;
fieldName = field.name;
}
++level;
}
if (txtIdx !== -1 && txtIdx < markdown.length) {
fieldsToReport.push(fields.map((f) => f.title).join('/'));
const posStart = editor.document.positionAt(txtIdx);
const posEnd = editor.document.positionAt(txtIdx + 1 + fieldName.length);
const diagnostic: vscode.Diagnostic = {
code: '',
message: `This ${fields
.map((f) => f.name)
.join('/')} field is required to contain a value.`,
range: new vscode.Range(posStart, posEnd),
severity: vscode.DiagnosticSeverity.Error,
source: 'Front Matter'
};
requiredDiagnostics.push(diagnostic);
}
}
if (collection.has(editor.document.uri)) {
const otherDiag = collection.get(editor.document.uri) || [];
collection.set(editor.document.uri, [...otherDiag, ...requiredDiagnostics]);
} else {
collection.set(editor.document.uri, [...requiredDiagnostics]);
}
if (fieldsToReport.length > 0) {
Notifications.showIfNotDisabled(
NOTIFICATION_TYPE.requiredFieldValidation,
'ERROR_ONCE',
`The following fields are required to contain a value: ${fieldsToReport.join(', ')}`
);
}
}
}
/**
* Find the line of the field
* @param text
* @param startIdx
* @param totalSpaces
* @param field
* @returns
*/
private static findFieldLine(
text: string,
startIdx: number,
totalSpaces: number,
field: Field
): number | undefined {
const crntIdx = text.indexOf(field.name, startIdx === -1 ? 0 : startIdx);
if (crntIdx > -1) {
// Find the linebreak before the current index
const txtFromStart = text.substring(0, crntIdx);
const splitLineBreaks = txtFromStart.split(/\r?\n/);
const lastLine = splitLineBreaks[splitLineBreaks.length - 1];
if (lastLine.length === totalSpaces) {
if (crntIdx > startIdx) {
return crntIdx;
}
} else {
return StatusListener.findFieldLine(text, crntIdx + field.name.length, totalSpaces, field);
}
}
return;
}
}

View File

@@ -1,55 +1,23 @@
import { Questions } from './../helpers/Questions';
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import { SETTING_CONTENT_DEFAULT_FILETYPE, SETTING_TEMPLATES_FOLDER, TelemetryEvent } from '../constants';
import {
SETTING_CONTENT_DEFAULT_FILETYPE,
SETTING_TEMPLATES_FOLDER,
TelemetryEvent
} from '../constants';
import { ArticleHelper, Settings } from '../helpers';
import { Article } from '.';
import { Notifications } from '../helpers/Notifications';
import { CONTEXT } from '../constants';
import { Project } from './Project';
import { Folders } from './Folders';
import { ContentType } from '../helpers/ContentType';
import { ContentType as IContentType } from '../models';
import { PagesListener } from '../listeners/dashboard';
import { extname } from 'path';
import { Telemetry } from '../helpers/Telemetry';
import { writeFileAsync, copyFileAsync } from '../utils';
export class Template {
/**
* Check if the template folder is available
*/
public static async init() {
const isInitialized = await Template.isInitialized();
await vscode.commands.executeCommand('setContext', CONTEXT.canInit, !isInitialized);
if (isInitialized) {
await vscode.commands.executeCommand('setContext', CONTEXT.initialized, true);
}
}
/**
* Check if the project is already initialized
*/
public static async isInitialized() {
const wsFolder = Folders.getWorkspaceFolder();
const folder = Template.getSettings();
if (!folder || !wsFolder) {
return false;
}
const templatePath = vscode.Uri.file(path.join(wsFolder.fsPath, folder));
try {
await vscode.workspace.fs.stat(templatePath);
return true;
} catch (e) {
return false;
}
}
/**
* Generate a template
*/
@@ -62,7 +30,8 @@ export class Template {
const article = ArticleHelper.getFrontMatter(editor);
const clonedArticle = Object.assign({}, article);
const titleValue = await vscode.window.showInputBox({
const titleValue = await vscode.window.showInputBox({
title: `Template title`,
prompt: `What name would you like to give your template?`,
placeHolder: `article`,
ignoreFocusOut: true
@@ -73,27 +42,30 @@ export class Template {
return;
}
const keepContents = await vscode.window.showQuickPick(
["yes", "no"],
{
canPickMany: false,
placeHolder: `Do you want to keep the contents for the template?`,
ignoreFocusOut: true
}
);
const keepContents = await vscode.window.showQuickPick(['yes', 'no'], {
title: `Keep contents`,
canPickMany: false,
placeHolder: `Do you want to keep the contents for the template?`,
ignoreFocusOut: true
});
if (!keepContents) {
Notifications.warning(`You did not pick any of the options for keeping the template its content.`);
Notifications.warning(
`You did not pick any of the options for keeping the template its content.`
);
return;
}
await Project.init(false);
const templatePath = Project.templatePath();
if (templatePath) {
let fileContents = ArticleHelper.stringifyFrontMatter(keepContents === "no" ? "" : clonedArticle.content, clonedArticle.data);
const fileContents = ArticleHelper.stringifyFrontMatter(
keepContents === 'no' ? '' : clonedArticle.content,
clonedArticle.data
);
const templateFile = path.join(templatePath.fsPath, `${titleValue}.${fileType}`);
fs.writeFileSync(templateFile, fileContents, { encoding: "utf-8" });
await writeFileAsync(templateFile, fileContents, { encoding: 'utf-8' });
Notifications.info(`Template created and is now available in your ${folder} folder.`);
}
@@ -111,7 +83,10 @@ export class Template {
return;
}
return await vscode.workspace.findFiles(`${folder}/**/*`, "**/node_modules/**,**/archetypes/**");
return await vscode.workspace.findFiles(
`${folder}/**/*`,
'**/node_modules/**,**/archetypes/**'
);
}
/**
@@ -131,10 +106,14 @@ export class Template {
return;
}
const selectedTemplate = await vscode.window.showQuickPick(templates.map(t => path.basename(t.fsPath)), {
placeHolder: `Select the content template to use`,
ignoreFocusOut: true
});
const selectedTemplate = await vscode.window.showQuickPick(
templates.map((t) => path.basename(t.fsPath)),
{
title: `Select a template`,
placeHolder: `Select the content template to use`,
ignoreFocusOut: true
}
);
if (!selectedTemplate) {
Notifications.warning(`No template selected.`);
return;
@@ -146,40 +125,53 @@ export class Template {
}
// Start the template read
const template = templates.find(t => t.fsPath.endsWith(selectedTemplate));
const template = templates.find((t) => t.fsPath.endsWith(selectedTemplate));
if (!template) {
Notifications.warning(`Content template could not be found.`);
return;
}
const templateData = ArticleHelper.getFrontMatterByPath(template.fsPath);
const templateData = await ArticleHelper.getFrontMatterByPath(template.fsPath);
let contentType: IContentType | undefined;
if (templateData && templateData.data && templateData.data.type) {
contentType = contentTypes?.find(t => t.name === templateData.data.type);
contentType = contentTypes?.find((t) => t.name === templateData.data.type);
}
const fileExtension = extname(template.fsPath).replace(".", "");
let newFilePath: string | undefined = ArticleHelper.createContent(contentType, folderPath, titleValue, fileExtension);
const fileExtension = extname(template.fsPath).replace('.', '');
const newFilePath: string | undefined = await ArticleHelper.createContent(
contentType,
folderPath,
titleValue,
fileExtension
);
if (!newFilePath) {
return;
}
// Start the new file creation
fs.copyFileSync(template.fsPath, newFilePath);
await copyFileAsync(template.fsPath, newFilePath);
// Update the properties inside the template
let frontMatter = ArticleHelper.getFrontMatterByPath(newFilePath);
let frontMatter = await ArticleHelper.getFrontMatterByPath(newFilePath);
if (!frontMatter) {
Notifications.warning(`Something failed when retrieving the newly created file.`);
return;
}
if (frontMatter.data) {
frontMatter.data = ArticleHelper.updatePlaceholders(frontMatter.data, titleValue);
frontMatter.data = await ArticleHelper.updatePlaceholders(
frontMatter.data,
titleValue,
newFilePath
);
frontMatter = Article.updateDate(frontMatter);
fs.writeFileSync(newFilePath, ArticleHelper.stringifyFrontMatter(frontMatter.content, frontMatter.data), { encoding: "utf8" });
await writeFileAsync(
newFilePath,
ArticleHelper.stringifyFrontMatter(frontMatter.content, frontMatter.data),
{ encoding: 'utf8' }
);
await vscode.commands.executeCommand('vscode.open', vscode.Uri.file(newFilePath));
}
@@ -204,4 +196,4 @@ export class Template {
const folder = Settings.get<string>(SETTING_TEMPLATES_FOLDER);
return folder;
}
}
}

View File

@@ -1,6 +1,6 @@
import { commands, window, Selection, QuickPickItem } from "vscode";
import { COMMAND_NAME, CONTEXT, SETTING_CONTENT_WYSIWYG } from "../constants";
import { Settings } from "../helpers";
import { commands, window, Selection, QuickPickItem, TextEditor } from 'vscode';
import { COMMAND_NAME, CONTEXT, SETTING_CONTENT_WYSIWYG } from '../constants';
import { Settings } from '../helpers';
enum MarkupType {
bold = 1,
@@ -12,18 +12,17 @@ enum MarkupType {
heading,
unorderedList,
orderedList,
taskList
taskList,
hyperlink
}
export class Wysiwyg {
/**
* Registers the markup commands for the WYSIWYG controls
* @param subscriptions
* @returns
* @param subscriptions
* @returns
*/
public static async registerCommands(subscriptions: any) {
public static async registerCommands(subscriptions: unknown[]) {
const wysiwygEnabled = Settings.get(SETTING_CONTENT_WYSIWYG);
if (!wysiwygEnabled) {
@@ -33,58 +32,123 @@ export class Wysiwyg {
await commands.executeCommand('setContext', CONTEXT.wysiwyg, true);
// Surrounding markup
subscriptions.push(commands.registerCommand(COMMAND_NAME.bold, () => this.addMarkup(MarkupType.bold)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.italic, () => this.addMarkup(MarkupType.italic)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.strikethrough, () => this.addMarkup(MarkupType.strikethrough)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.code, () => this.addMarkup(MarkupType.code)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.codeblock, () => this.addMarkup(MarkupType.codeblock)));
subscriptions.push(
commands.registerCommand(COMMAND_NAME.bold, () => this.addMarkup(MarkupType.bold))
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.italic, () => this.addMarkup(MarkupType.italic))
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.strikethrough, () =>
this.addMarkup(MarkupType.strikethrough)
)
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.code, () => this.addMarkup(MarkupType.code))
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.codeblock, () => this.addMarkup(MarkupType.codeblock))
);
// Prefix markup
subscriptions.push(commands.registerCommand(COMMAND_NAME.heading, () => this.addMarkup(MarkupType.heading)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.blockquote, () => this.addMarkup(MarkupType.blockquote)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.unorderedlist, () => this.addMarkup(MarkupType.unorderedList)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.orderedlist, () => this.addMarkup(MarkupType.orderedList)));
subscriptions.push(commands.registerCommand(COMMAND_NAME.taskList, () => this.addMarkup(MarkupType.taskList)));
subscriptions.push(
commands.registerCommand(COMMAND_NAME.heading, () => this.addMarkup(MarkupType.heading))
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.blockquote, () => this.addMarkup(MarkupType.blockquote))
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.unorderedlist, () =>
this.addMarkup(MarkupType.unorderedList)
)
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.orderedlist, () =>
this.addMarkup(MarkupType.orderedList)
)
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.taskList, () => this.addMarkup(MarkupType.taskList))
);
// Other markup
subscriptions.push(
commands.registerCommand(COMMAND_NAME.hyperlink, () => this.addMarkup(MarkupType.hyperlink))
);
// Options
subscriptions.push(commands.registerCommand(COMMAND_NAME.options, async () => {
const qpItems: QuickPickItem[] = [
{ label: "$(list-unordered) Unordered list", detail: "Add an unordered list", alwaysShow: true, },
{ label: "$(list-ordered) Ordered list", detail: "Add an ordered list", alwaysShow: true },
{ label: "$(tasklist) Task list", detail: "Add a task list", alwaysShow: true },
{ label: "$(code) Code", detail: "Add inline code snippet", alwaysShow: true },
{ label: "$(symbol-namespace) Code block", detail: "Add a code block", alwaysShow: true },
{ label: "$(quote) Blockquote", detail: "Add a blockquote", alwaysShow: true },
]
subscriptions.push(
commands.registerCommand(COMMAND_NAME.options, async () => {
const qpItems: QuickPickItem[] = [
{
label: '$(list-unordered) Unordered list',
detail: 'Add an unordered list',
alwaysShow: true
},
{
label: '$(list-ordered) Ordered list',
detail: 'Add an ordered list',
alwaysShow: true
},
{
label: '$(tasklist) Task list',
detail: 'Add a task list',
alwaysShow: true
},
{
label: '$(code) Code',
detail: 'Add inline code snippet',
alwaysShow: true
},
{
label: '$(symbol-namespace) Code block',
detail: 'Add a code block',
alwaysShow: true
},
{
label: '$(quote) Blockquote',
detail: 'Add a blockquote',
alwaysShow: true
},
{
label: '$(symbol-text) Strikethrough',
detail: 'Add a strikethrough',
alwaysShow: true
}
];
const option = await window.showQuickPick([ ...qpItems ], {
placeHolder: "Which type of markup would you like to insert?",
canPickMany: false,
ignoreFocusOut: true
});
const option = await window.showQuickPick([...qpItems], {
title: 'WYSIWYG Options',
placeHolder: 'Which type of markup would you like to insert?',
canPickMany: false,
ignoreFocusOut: true
});
if (option) {
if (option.label === qpItems[0].label) {
await this.addMarkup(MarkupType.unorderedList);
} else if (option.label === qpItems[1].label) {
await this.addMarkup(MarkupType.orderedList);
} else if (option.label === qpItems[2].label) {
await this.addMarkup(MarkupType.taskList);
} else if (option.label === qpItems[3].label) {
await this.addMarkup(MarkupType.code);
} else if (option.label === qpItems[4].label) {
await this.addMarkup(MarkupType.codeblock);
} else if (option.label === qpItems[5].label) {
await this.addMarkup(MarkupType.blockquote);
if (option) {
if (option.label === qpItems[0].label) {
await this.addMarkup(MarkupType.unorderedList);
} else if (option.label === qpItems[1].label) {
await this.addMarkup(MarkupType.orderedList);
} else if (option.label === qpItems[2].label) {
await this.addMarkup(MarkupType.taskList);
} else if (option.label === qpItems[3].label) {
await this.addMarkup(MarkupType.code);
} else if (option.label === qpItems[4].label) {
await this.addMarkup(MarkupType.codeblock);
} else if (option.label === qpItems[5].label) {
await this.addMarkup(MarkupType.blockquote);
} else if (option.label === qpItems[6].label) {
await this.addMarkup(MarkupType.strikethrough);
}
}
}
}));
})
);
}
/**
* Add the markup to the content
* @param type
* @returns
* @param type
* @returns
*/
private static async addMarkup(type: MarkupType) {
const editor = window.activeTextEditor;
@@ -95,6 +159,10 @@ export class Wysiwyg {
const selection = editor.selection;
const hasTextSelection = !selection.isEmpty;
if (type === MarkupType.hyperlink) {
return this.addHyperlink(editor, selection);
}
const markers = this.getMarkers(type);
if (!markers) {
return;
@@ -106,18 +174,21 @@ export class Wysiwyg {
// Replace the selection and surround with the markup
const selectionText = editor.document.getText(selection);
const txt = await this.insertText(markers, type, selectionText);
editor.edit(builder => {
editor.edit((builder) => {
builder.replace(selection, txt);
});
} else {
const txt = await this.insertText(markers, type);
// Insert the markers where cursor is located.
const markerLength = this.isMarkupWrapping(type) ? txt.length + 1 : markers.length;
let newPosition = crntSelection.with(crntSelection.line, crntSelection.character + markerLength);
let newPosition = crntSelection.with(
crntSelection.line,
crntSelection.character + markerLength
);
await editor.edit(builder => {
await editor.edit((builder) => {
builder.insert(newPosition, txt);
});
@@ -130,13 +201,61 @@ export class Wysiwyg {
}
/**
* Check if the text will be wrapped
* @param type
* @returns
* Add a hyperlink to the content
* @returns void
*/
private static isMarkupWrapping(type: MarkupType) {
private static async addHyperlink(editor: TextEditor, selection: Selection) {
const hasTextSelection = !selection.isEmpty;
const linkText = hasTextSelection ? editor.document.getText(selection) : '';
const link = await window.showInputBox({
title: 'WYSIWYG Hyperlink',
placeHolder: 'Enter the URL',
prompt: 'Enter the URL',
value: linkText,
ignoreFocusOut: true
});
const text = await window.showInputBox({
title: 'WYSIWYG Text',
prompt: 'Enter the text for the hyperlink',
placeHolder: 'Enter the text for the hyperlink',
value: linkText,
ignoreFocusOut: true
});
if (link) {
const txt = `[${text || link}](${link})`;
if (hasTextSelection) {
editor.edit((builder) => {
builder.replace(selection, txt);
});
} else {
const crntSelection = selection.active;
const markerLength = txt.length;
const newPosition = crntSelection.with(
crntSelection.line,
crntSelection.character + markerLength
);
await editor.edit((builder) => {
builder.insert(newPosition, txt);
});
editor.selection = new Selection(newPosition, newPosition);
}
}
}
/**
* Check if the text will be wrapped
* @param type
* @returns
*/
private static isMarkupWrapping(type: MarkupType) {
return (
type === MarkupType.blockquote ||
type === MarkupType.blockquote ||
type === MarkupType.heading ||
type === MarkupType.unorderedList ||
type === MarkupType.orderedList ||
@@ -147,38 +266,39 @@ export class Wysiwyg {
/**
* Insert text at the current cursor position
*/
private static async insertText(marker: string | undefined, type: MarkupType, text: string | null = null) {
private static async insertText(
marker: string | undefined,
type: MarkupType,
text: string | null = null
) {
const crntText = text || this.lineBreak(type);
if (this.isMarkupWrapping(type)) {
if (type === MarkupType.heading) {
const headingLvl = await window.showQuickPick([
"Heading 1",
"Heading 2",
"Heading 3",
"Heading 4",
"Heading 5",
"Heading 6"
], {
canPickMany: false,
placeHolder: "Which heading level do you want to insert?",
ignoreFocusOut: true
});
const headingLvl = await window.showQuickPick(
['Heading 1', 'Heading 2', 'Heading 3', 'Heading 4', 'Heading 5', 'Heading 6'],
{
title: 'Heading Level',
canPickMany: false,
placeHolder: 'Which heading level do you want to insert?',
ignoreFocusOut: true
}
);
if (headingLvl) {
const headingNr = parseInt(headingLvl.replace("Heading ", ""));
const headingNr = parseInt(headingLvl.replace('Heading ', ''));
return `${Array(headingNr + 1).join(marker)} ${crntText}`;
}
}
if (type === MarkupType.unorderedList || type === MarkupType.taskList) {
const lines = crntText.split("\n").map(line => `${marker} ${line}`);
return lines.join("\n");
const lines = crntText.split('\n').map((line) => `${marker} ${line}`);
return lines.join('\n');
}
if (type === MarkupType.orderedList) {
const lines = crntText.split("\n").map((line, idx) => `${idx+1}. ${line}`);
return lines.join("\n");
const lines = crntText.split('\n').map((line, idx) => `${idx + 1}. ${line}`);
return lines.join('\n');
}
return `${marker} ${crntText}`;
@@ -189,23 +309,23 @@ export class Wysiwyg {
/**
* Check if linebreak needs to be added
* @param type
* @returns
* @param type
* @returns
*/
private static lineBreak(type: MarkupType) {
if (type === MarkupType.codeblock) {
return `\n\n`;
}
return "";
return '';
}
/**
* Retrieve the type of markers
* @param type
* @returns
* @param type
* @returns
*/
private static getMarkers(type: MarkupType) {
switch(type) {
switch (type) {
case MarkupType.bold:
return `**`;
case MarkupType.italic:
@@ -213,21 +333,21 @@ export class Wysiwyg {
case MarkupType.strikethrough:
return `~~`;
case MarkupType.code:
return "`";
return '`';
case MarkupType.codeblock:
return "```";
return '```';
case MarkupType.blockquote:
return ">";
return '>';
case MarkupType.heading:
return "#";
return '#';
case MarkupType.unorderedList:
return "-";
return '-';
case MarkupType.orderedList:
return "1.";
return '1.';
case MarkupType.taskList:
return "- [ ]";
return '- [ ]';
default:
return;
}
}
}
}

View File

@@ -1,3 +1,14 @@
export * from './Article';
export * from './Backers';
export * from './Cache';
export * from './Chatbot';
export * from './Content';
export * from './Dashboard';
export * from './Diagnostics';
export * from './Folders';
export * from './Preview';
export * from './Project';
export * from './Settings';
export * from './StatusListener';
export * from './Template';
export * from './Wysiwyg';

View File

@@ -6,9 +6,13 @@ export interface IFeatureFlagProps {
alternative?: JSX.Element;
}
export const FeatureFlag: React.FunctionComponent<IFeatureFlagProps> = ({ flag, features, alternative, children }: React.PropsWithChildren<IFeatureFlagProps>) => {
if (!features ||( features.length > 0 && !features.includes(flag))) {
export const FeatureFlag: React.FunctionComponent<IFeatureFlagProps> = ({
flag,
features,
alternative,
children
}: React.PropsWithChildren<IFeatureFlagProps>) => {
if (!features || (features.length > 0 && !features.includes(flag))) {
if (alternative) {
return alternative;
}
@@ -16,11 +20,5 @@ export const FeatureFlag: React.FunctionComponent<IFeatureFlagProps> = ({ flag,
return null;
}
return (
<>
{children}
</>
);
};
return <>{children}</>;
};

View File

@@ -0,0 +1,14 @@
import * as React from 'react';
export interface IChatIconProps {
className?: string;
}
export const ChatIcon: React.FunctionComponent<IChatIconProps> = ({ className }: React.PropsWithChildren<IChatIconProps>) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" className={className || 'h-4 w-4'} viewBox="0 0 32 32">
<path fill="currentcolor" d="M16 19a6.99 6.99 0 0 1-5.833-3.129l1.666-1.107a5 5 0 0 0 8.334 0l1.666 1.107A6.99 6.99 0 0 1 16 19zm4-11a2 2 0 1 0 2 2a1.98 1.98 0 0 0-2-2zm-8 0a2 2 0 1 0 2 2a1.98 1.98 0 0 0-2-2z" />
<path fill="currentcolor" d="M17.736 30L16 29l4-7h6a1.997 1.997 0 0 0 2-2V6a1.997 1.997 0 0 0-2-2H6a1.997 1.997 0 0 0-2 2v14a1.997 1.997 0 0 0 2 2h9v2H6a4 4 0 0 1-4-4V6a3.999 3.999 0 0 1 4-4h20a3.999 3.999 0 0 1 4 4v14a4 4 0 0 1-4 4h-4.835Z" />
</svg>
);
};

View File

@@ -4,10 +4,22 @@ export interface ICompressIconProps {
className?: string;
}
export const CompressIcon: React.FunctionComponent<ICompressIconProps> = ({className}: React.PropsWithChildren<ICompressIconProps>) => {
export const CompressIcon: React.FunctionComponent<ICompressIconProps> = ({
className
}: React.PropsWithChildren<ICompressIconProps>) => {
return (
<svg className={className || ""} aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="currentColor" d="M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"></path>
<svg
className={className || ''}
aria-hidden="true"
focusable="false"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
>
<path
fill="currentColor"
d="M436 192H312c-13.3 0-24-10.7-24-24V44c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v84h84c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm-276-24V44c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v84H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24zm0 300V344c0-13.3-10.7-24-24-24H12c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-84h84c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12H312c-13.3 0-24 10.7-24 24v124c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12z"
></path>
</svg>
);
};
};

View File

@@ -4,10 +4,16 @@ export interface IMergeIconProps {
className: string;
}
export const MergeIcon: React.FunctionComponent<IMergeIconProps> = ({className}: React.PropsWithChildren<IMergeIconProps>) => {
export const MergeIcon: React.FunctionComponent<IMergeIconProps> = ({
className
}: React.PropsWithChildren<IMergeIconProps>) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" className={className}>
<path xmlns="http://www.w3.org/2000/svg" d="M7.586 8.00366L4 8.00366C3.44772 8.00366 3 7.55595 3 7.00366C3 6.45138 3.44772 6.00366 4 6.00366L8 6.00366C8.26509 6.00366 8.51933 6.10892 8.70685 6.2963L13.414 11H18.5845L15.2931 7.71103C14.9025 7.32065 14.9023 6.68748 15.2926 6.29681C15.683 5.90615 16.3162 5.90592 16.7068 6.2963L21.7068 11.2926C21.8945 11.4802 22 11.7346 22 11.9998C22 12.2651 21.8947 12.5195 21.7071 12.7071L16.7071 17.7071C16.3166 18.0976 15.6834 18.0976 15.2929 17.7071C14.9024 17.3166 14.9024 16.6834 15.2929 16.2929L18.5858 13H13.4142L8.70711 17.7071C8.51957 17.8947 8.26522 18 8 18H4C3.44772 18 3 17.5523 3 17C3 16.4477 3.44772 16 4 16H7.58579L11.5855 12.0003L7.586 8.00366Z" fill="currentcolor"/>
<path
xmlns="http://www.w3.org/2000/svg"
d="M7.586 8.00366L4 8.00366C3.44772 8.00366 3 7.55595 3 7.00366C3 6.45138 3.44772 6.00366 4 6.00366L8 6.00366C8.26509 6.00366 8.51933 6.10892 8.70685 6.2963L13.414 11H18.5845L15.2931 7.71103C14.9025 7.32065 14.9023 6.68748 15.2926 6.29681C15.683 5.90615 16.3162 5.90592 16.7068 6.2963L21.7068 11.2926C21.8945 11.4802 22 11.7346 22 11.9998C22 12.2651 21.8947 12.5195 21.7071 12.7071L16.7071 17.7071C16.3166 18.0976 15.6834 18.0976 15.2929 17.7071C14.9024 17.3166 14.9024 16.6834 15.2929 16.2929L18.5858 13H13.4142L8.70711 17.7071C8.51957 17.8947 8.26522 18 8 18H4C3.44772 18 3 17.5523 3 17C3 16.4477 3.44772 16 4 16H7.58579L11.5855 12.0003L7.586 8.00366Z"
fill="currentcolor"
/>
</svg>
);
};
};

View File

@@ -1,23 +1,21 @@
import * as invariant from 'invariant';
import { createAutoField } from 'uniforms';
import { PreviewImageField } from '../../panelWebView/components/Fields/PreviewImageField';
export { AutoFieldProps } from 'uniforms';
import BoolField from './BoolField';
import DateField from './DateField';
import ListField from './ListField';
import LongTextField from './LongTextField';
import NestField from './NestField';
import NumField from './NumField';
import RadioField from './RadioField';
import SelectField from './SelectField';
import TextField from './TextField';
import UnknownField from './UnknownField';
const AutoField = createAutoField(props => {
const AutoField = createAutoField((props) => {
if (props.allowedValues) {
return props.checkboxes && props.fieldType !== Array
? RadioField
: SelectField;
return props.checkboxes && props.fieldType !== Array ? RadioField : SelectField;
}
switch (props.fieldType) {
@@ -32,7 +30,12 @@ const AutoField = createAutoField(props => {
case Object:
return NestField;
case String:
if (props["multiline"]) {
return LongTextField;
}
return TextField;
default:
return UnknownField;
}
return invariant(false, 'Unsupported field type: %s', props.fieldType);

View File

@@ -23,7 +23,7 @@ export default function AutoFields({
element,
props,
(fields ?? schema.getSubfields())
.filter(field => !omitFields.includes(field))
.map(field => createElement(autoField, { key: field, name: field })),
.filter((field) => !omitFields.includes(field))
.map((field) => createElement(autoField, { key: field, name: field }))
);
}

View File

@@ -2,8 +2,9 @@ import { AutoForm } from 'uniforms';
import ValidatedQuickForm from './ValidatedQuickForm';
function Auto(parent: any) {
class _ extends AutoForm.Auto(parent) {
function Auto(parent: unknown) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
class _ extends AutoForm.Auto(parent as any) {
static Auto = Auto;
}

View File

@@ -1,5 +1,6 @@
import { BaseForm } from 'uniforms';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function Unstyled(parent: any) {
class _ extends parent {
static Unstyled = Unstyled;

View File

@@ -5,7 +5,7 @@
height: 24px;
}
.field__toggle input {
.field__toggle input {
opacity: 0;
width: 0;
height: 0;
@@ -18,22 +18,25 @@
left: 0;
right: 0;
bottom: 0;
background-color: var(--frontmatter-toggle-secondaryBackground, var(--vscode-button-secondaryBackground));
-webkit-transition: .4s;
transition: .4s;
background-color: var(
--frontmatter-toggle-secondaryBackground,
var(--vscode-button-secondaryBackground)
);
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 34px;
}
.field__toggle__slider:before {
position: absolute;
content: "";
content: '';
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 50%;
}
@@ -49,4 +52,4 @@ input:checked + .field__toggle__slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
}

View File

@@ -24,7 +24,7 @@ function Bool({
return (
<div {...filterDOMProps(props)}>
<LabelField label={label} id={id} required={props.required} />
<label className="field__toggle">
<input
checked={value || false}

View File

@@ -36,7 +36,7 @@ function Date({
max={dateFormat(max)}
min={dateFormat(min)}
name={name}
onChange={event => {
onChange={(event) => {
const date = new DateConstructor(event.target.valueAsNumber);
if (date.getFullYear() < 10000) {
onChange(date);

View File

@@ -4,16 +4,14 @@ import { Override, connectField, filterDOMProps } from 'uniforms';
export type ErrorFieldProps = Override<
Omit<HTMLProps<HTMLDivElement>, 'onChange'>,
{ error?: any; errorMessage?: string }
{ error?: unknown; errorMessage?: string }
>;
function Error({ children, error, errorMessage, ...props }: ErrorFieldProps) {
return !error ? null : (
<div {...filterDOMProps(props)}>{children || errorMessage}</div>
);
return !error ? null : <div {...filterDOMProps(props)}>{children || errorMessage}</div>;
}
export default connectField<ErrorFieldProps>(Error, {
initialValue: false,
kind: 'leaf',
kind: 'leaf'
});

View File

@@ -1,7 +1,8 @@
.autoform-error {
background-color: var(--frontmatter-error-background, var(--vscode-inputValidation-errorBackground));
background-color: var(
--frontmatter-error-background,
var(--vscode-inputValidation-errorBackground)
);
border: 1px solid var(--frontmatter-error-border, var(--vscode-inputValidation-errorBorder));
border-radius: 2px;
margin: 20px 0px;
@@ -15,4 +16,4 @@
li {
text-transform: capitalize;
}
}
}

View File

@@ -8,7 +8,7 @@ export type ErrorsFieldProps = HTMLProps<HTMLDivElement>;
export default function ErrorsField(props: ErrorsFieldProps) {
const { error, schema } = useForm();
return !error && !props.children ? null : (
<div className='autoform-error'>
<div className="autoform-error">
<div {...filterDOMProps(props)}>
{props.children}

View File

@@ -2,18 +2,20 @@ import * as React from 'react';
import { HTMLProps, Ref, useEffect } from 'react';
import { Override, filterDOMProps, useField } from 'uniforms';
type ValueType = string | number | readonly string[] | undefined;
export type HiddenFieldProps = Override<
HTMLProps<HTMLInputElement>,
{
inputRef?: Ref<HTMLInputElement>;
name: string;
noDOM?: boolean;
value?: any;
value?: ValueType;
}
>;
export default function HiddenField({ value, ...rawProps }: HiddenFieldProps) {
const props = useField(rawProps.name, rawProps, { initialValue: false })[0];
const defaultValue = (props.value as ValueType) ?? '';
useEffect(() => {
if (value !== undefined && value !== props.value) {
@@ -28,7 +30,7 @@ export default function HiddenField({ value, ...rawProps }: HiddenFieldProps) {
readOnly={props.readOnly}
ref={props.inputRef}
type="hidden"
value={value ?? props.value ?? ''}
value={value ?? defaultValue}
{...filterDOMProps(props)}
/>
);

View File

@@ -1,5 +1,3 @@
.autoform__label {
display: block;
margin-bottom: 0.5rem;
@@ -11,4 +9,4 @@
color: var(--vscode-inputValidation-errorBorder);
margin-left: 0.25rem;
}
}
}

View File

@@ -1,6 +1,8 @@
import * as React from 'react';
import { ReactNode } from 'react';
import './LabelField.css';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../localization';
export interface ILabelFieldProps {
id: string;
@@ -8,13 +10,19 @@ export interface ILabelFieldProps {
required?: boolean;
}
export const LabelField: React.FunctionComponent<ILabelFieldProps> = ({ label, id, required }: React.PropsWithChildren<ILabelFieldProps>) => {
return (
label ? (
<label className="autoform__label" htmlFor={id}>
{label}
{required && <span title='Required field' className='autoform__label__required'>*</span>}
</label>
) : null
);
};
export const LabelField: React.FunctionComponent<ILabelFieldProps> = ({
label,
id,
required
}: React.PropsWithChildren<ILabelFieldProps>) => {
return label ? (
<label className="autoform__label" htmlFor={id}>
{label}
{required && (
<span title={l10n.t(LocalizationKey.fieldRequired)} className="autoform__label__required">
*
</span>
)}
</label>
) : null;
};

View File

@@ -1,12 +1,10 @@
.autoform__list_add_field {
display: flex;
padding: 5px;
border: 1px dashed var(--frontmatter-field-border, var(--vscode-editor-foreground));
width: 100%;
justify-content: center;
margin-top: .5rem;
margin-top: 0.5rem;
&:hover {
border-color: var(--frontmatter-field-borderActive, var(--vscode-button-background));
@@ -18,4 +16,4 @@
height: 1rem;
width: 1rem;
}
}
}

View File

@@ -1,51 +1,38 @@
import { PlusIcon } from '@heroicons/react/outline';
import * as React from 'react';
import {
HTMLFieldProps,
connectField,
filterDOMProps,
joinName,
useField,
} from 'uniforms';
import { HTMLFieldProps, connectField, filterDOMProps, joinName, useField } from 'uniforms';
import './ListAddField.css';
type ParentFieldType = { initialCount?: number; maxCount?: number };
type ValueType = string | readonly string[] | undefined;
export type ListAddFieldProps = HTMLFieldProps<
unknown,
ValueType,
HTMLSpanElement,
{ initialCount?: number }
>;
function ListAdd({
disabled,
initialCount,
name,
readOnly,
value,
...props
}: ListAddFieldProps) {
function ListAdd({ disabled, initialCount, name, readOnly, value, ...props }: ListAddFieldProps) {
const nameParts = joinName(null, name);
const parentName = joinName(nameParts.slice(0, -1));
const parent = useField<
{ initialCount?: number; maxCount?: number },
unknown[]
>(parentName, { initialCount }, { absoluteName: true })[0];
const limitNotReached =
!disabled && !(parent.maxCount! <= parent.value!.length);
const limitNotReached = !disabled && !(parent.maxCount! <= parent.value!.length);
function onAction(event: React.KeyboardEvent | React.MouseEvent) {
if (
limitNotReached &&
!readOnly &&
(!('key' in event) || event.key === 'Enter')
) {
parent.onChange(parent.value!.concat([Object.assign({}, value)]));
if (limitNotReached && !readOnly && (!('key' in event) || event.key === 'Enter')) {
parent.onChange(parent.value!.concat([value]));
}
}
return (
<span
className='autoform__list_add_field'
className="autoform__list_add_field"
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{...filterDOMProps(props as any)}
onClick={onAction}
onKeyDown={onAction}
@@ -59,5 +46,5 @@ function ListAdd({
export default connectField<ListAddFieldProps>(ListAdd, {
initialValue: false,
kind: 'leaf',
kind: 'leaf'
});

View File

@@ -1,10 +1,8 @@
.autoform__list_del_field {
display: flex;
width: 100%;
justify-content: center;
margin-top: .5rem;
margin-top: 0.5rem;
&:hover {
border-color: var(--vscode-button-background);
@@ -16,12 +14,12 @@
height: 1px;
background: var(--frontmatter-list-border, var(--vscode-editor-foreground));
width: 100%;
margin-right: .5rem;
margin-top: .5rem;
margin-right: 0.5rem;
margin-top: 0.5rem;
}
svg {
height: 1.25rem;
width: 1.25rem;
}
}
}

View File

@@ -1,12 +1,6 @@
import { TrashIcon } from '@heroicons/react/outline';
import * as React from 'react';
import {
HTMLFieldProps,
connectField,
filterDOMProps,
joinName,
useField,
} from 'uniforms';
import { HTMLFieldProps, connectField, filterDOMProps, joinName, useField } from 'uniforms';
import './ListDelField.css';
export type ListDelFieldProps = HTMLFieldProps<unknown, HTMLSpanElement>;
@@ -15,26 +9,19 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
const nameParts = joinName(null, name);
const nameIndex = +nameParts[nameParts.length - 1];
const parentName = joinName(nameParts.slice(0, -1));
const parent = useField<{ minCount?: number }, unknown[]>(
parentName,
{},
{ absoluteName: true },
)[0];
const parent = {
minCount: 0,
value: [],
...useField<{ minCount?: number }, unknown[]>(parentName, {}, { absoluteName: true })[0]
};
const limitNotReached =
!disabled && !(parent.minCount! >= parent.value!.length);
const limitNotReached = !disabled && !(parent.minCount >= parent.value.length);
function onAction(
event:
| React.KeyboardEvent<HTMLSpanElement>
| React.MouseEvent<HTMLSpanElement, MouseEvent>,
event: React.KeyboardEvent<HTMLSpanElement> | React.MouseEvent<HTMLSpanElement, MouseEvent>
) {
if (
limitNotReached &&
!readOnly &&
(!('key' in event) || event.key === 'Enter')
) {
const value = parent.value!.slice();
if (limitNotReached && !readOnly && (!('key' in event) || event.key === 'Enter')) {
const value = parent.value.slice();
value.splice(nameIndex, 1);
parent.onChange(value);
}
@@ -42,22 +29,20 @@ function ListDel({ disabled, name, readOnly, ...props }: ListDelFieldProps) {
return (
<span
className='autoform__list_del_field'
className="autoform__list_del_field"
{...filterDOMProps(props)}
onClick={onAction}
onKeyDown={onAction}
role="button"
tabIndex={0}
>
<div className='line'></div>
<div className="line"></div>
<TrashIcon />
</span>
);
}
export default connectField<ListDelFieldProps>(ListDel, {
initialValue: false,
kind: 'leaf',
kind: 'leaf'
});

View File

@@ -1,8 +1,6 @@
.autoform__list_field {
margin-bottom: 1rem;
margin-top: 1rem;
padding: 10px;
border: 1px solid var(--frontmatter-list-border, rgba(255, 255, 255, 0.2));
}
}

View File

@@ -7,6 +7,7 @@ import ListItemField from './ListItemField';
import './ListField.css';
import { LabelField } from './LabelField';
import { AutoField } from 'uniforms-unstyled';
export type ListFieldProps = HTMLFieldProps<
unknown[],
@@ -27,15 +28,15 @@ function List({
<LabelField label={label} id={props.id} required={props.required} />
{value?.map((item, itemIndex) =>
Children.map(children, (child, childIndex) =>
Children.map(children as React.ReactElement[], (child: React.ReactElement<any>, childIndex) =>
isValidElement(child)
? cloneElement(child, {
key: `${itemIndex}-${childIndex}`,
name: (child.props.name || "").replace('$', '' + itemIndex),
...itemProps,
})
: child,
),
? cloneElement(child as React.ReactElement<any>, {
key: `${itemIndex}-${childIndex}`,
name: ((child?.props as any)?.name || "").replace('$', '' + itemIndex),
...itemProps,
})
: child
)
)}
<ListAddField initialCount={initialCount} name="$" />

View File

@@ -7,9 +7,7 @@ import ListDelField from './ListDelField';
export type ListItemFieldProps = { children?: ReactNode; value?: unknown };
function ListItem({
children = <AutoField label={null} name="" />,
}: ListItemFieldProps) {
function ListItem({ children = <AutoField label={null} name="" /> }: ListItemFieldProps) {
return (
<div>
<ListDelField name="" />
@@ -19,5 +17,5 @@ function ListItem({
}
export default connectField<ListItemFieldProps>(ListItem, {
initialValue: false,
initialValue: false
});

View File

@@ -1,6 +1,7 @@
import * as React from 'react';
import { Ref } from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelField } from './LabelField';
export type LongTextFieldProps = HTMLFieldProps<
string,
@@ -22,13 +23,13 @@ function LongText({
}: LongTextFieldProps) {
return (
<div {...filterDOMProps(props)}>
{label && <label htmlFor={id}>{label}</label>}
<LabelField label={label} id={id} required={props.required} />
<textarea
disabled={disabled}
id={id}
name={name}
onChange={event => onChange(event.target.value)}
onChange={(event) => onChange(event.target.value)}
placeholder={placeholder}
readOnly={readOnly}
ref={inputRef}

View File

@@ -4,27 +4,14 @@ import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import AutoField from './AutoField';
import { LabelField } from './LabelField';
export type NestFieldProps = HTMLFieldProps<
object,
HTMLDivElement,
{ itemProps?: object }
>;
export type NestFieldProps = HTMLFieldProps<object, HTMLDivElement, { itemProps?: object }>;
function Nest({
children,
fields,
itemProps,
label,
...props
}: NestFieldProps) {
function Nest({ children, fields, itemProps, label, ...props }: NestFieldProps) {
return (
<div {...filterDOMProps(props)}>
<LabelField label={label} id={props.id} required={props.required} />
{children ||
fields.map(field => (
<AutoField key={field} name={field} {...itemProps} />
))}
{children || fields.map((field) => <AutoField key={field} name={field} {...itemProps} />)}
</div>
);
}

View File

@@ -35,7 +35,7 @@ function Num({
max={max}
min={min}
name={name}
onChange={event => {
onChange={(event) => {
const parse = decimal ? parseFloat : parseInt;
const value = parse(event.target.value);
onChange(isNaN(value) ? undefined : value);

View File

@@ -1,3 +1,4 @@
/* eslint-disable class-methods-use-this */
import { QuickForm } from 'uniforms';
import AutoField from './AutoField';
@@ -5,6 +6,7 @@ import BaseForm from './BaseForm';
import ErrorsField from './ErrorsField';
import SubmitField from './SubmitField';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function Quick(parent: any) {
class _ extends QuickForm.Quick(parent) {
static Quick = Quick;

View File

@@ -5,7 +5,7 @@ import { LabelField } from './LabelField';
const base64: typeof btoa =
typeof btoa === 'undefined'
? /* istanbul ignore next */ x => Buffer.from(x).toString('base64')
? /* istanbul ignore next */ (x) => Buffer.from(x).toString('base64')
: btoa;
const escape = (x: string) => base64(encodeURIComponent(x)).replace(/=+$/, '');
@@ -35,7 +35,7 @@ function Radio({
<div {...omit(filterDOMProps(props), ['checkboxes'])}>
<LabelField label={label} id={id} required={props.required} />
{allowedValues?.map(item => (
{allowedValues?.map((item) => (
<div key={item}>
<input
checked={item === value}
@@ -50,9 +50,7 @@ function Radio({
type="radio"
/>
<label htmlFor={`${id}-${escape(item)}`}>
{transform ? transform(item) : item}
</label>
<label htmlFor={`${id}-${escape(item)}`}>{transform ? transform(item) : item}</label>
</div>
))}
</div>

View File

@@ -1,5 +1,3 @@
.autoform__select_field {
color: var(--frontmatter-select-foreground, var(--vscode-editor-foreground));
}
}

View File

@@ -7,7 +7,7 @@ import './SelectField.css';
const base64: typeof btoa =
typeof btoa === 'undefined'
? /* istanbul ignore next */ x => Buffer.from(x).toString('base64')
? /* istanbul ignore next */ (x) => Buffer.from(x).toString('base64')
: btoa;
const escape = (x: string) => base64(encodeURIComponent(x)).replace(/=+$/, '');
@@ -24,7 +24,7 @@ export type SelectFieldProps = HTMLFieldProps<
>;
function Select({
allowedValues,
allowedValues = [],
checkboxes,
disabled,
fieldType,
@@ -38,21 +38,19 @@ function Select({
required,
disableItem,
transform,
value,
value = [],
...props
}: SelectFieldProps) {
const multiple = fieldType === Array;
return (
<div className='autoform__select_field' {...filterDOMProps(props)}>
<div className="autoform__select_field" {...filterDOMProps(props)}>
<LabelField label={label} id={id} required={required} />
{checkboxes ? (
allowedValues!.map(item => (
allowedValues.map((item) => (
<div key={item}>
<input
checked={
fieldType === Array ? value!.includes(item) : value === item
}
checked={fieldType === Array ? value.includes(item) : value === item}
disabled={disableItem?.(item) ?? disabled}
id={`${id}-${escape(item)}`}
name={name}
@@ -64,9 +62,7 @@ function Select({
type="checkbox"
/>
<label htmlFor={`${id}-${escape(item)}`}>
{transform ? transform(item) : item}
</label>
<label htmlFor={`${id}-${escape(item)}`}>{transform ? transform(item) : item}</label>
</div>
))
) : (
@@ -75,7 +71,7 @@ function Select({
id={id}
multiple={multiple}
name={name}
onChange={event => {
onChange={(event) => {
if (!readOnly) {
const item = event.target.value;
if (multiple) {
@@ -88,7 +84,7 @@ function Select({
}}
ref={inputRef}
value={value ?? ''}
style={{ width: "100%", padding: "0.5rem" }}
style={{ width: '100%', padding: '0.5rem' }}
>
{(!!placeholder || !required || value === undefined) && !multiple && (
<option value="" disabled={required} hidden={required}>
@@ -96,7 +92,7 @@ function Select({
</option>
)}
{allowedValues?.map(value => (
{allowedValues?.map((value) => (
<option disabled={disableItem?.(value)} key={value} value={value}>
{transform ? transform(value) : value}
</option>

View File

@@ -23,7 +23,6 @@ function Text({
value,
...props
}: TextFieldProps) {
return (
<div {...filterDOMProps(props)}>
<LabelField label={label} id={id} required={props.required} />
@@ -33,7 +32,7 @@ function Text({
disabled={disabled}
id={id}
name={name}
onChange={event => onChange(event.target.value)}
onChange={(event) => onChange(event.target.value)}
placeholder={placeholder}
readOnly={readOnly}
ref={inputRef}

View File

@@ -0,0 +1,39 @@
import { Ref } from 'react';
import * as React from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelField } from './LabelField';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../localization';
export type UnknownFieldProps = HTMLFieldProps<
string,
HTMLDivElement,
{ inputRef?: Ref<HTMLInputElement> }
>;
function UnknownField({
autoComplete,
disabled,
id,
inputRef,
label,
name,
onChange,
placeholder,
readOnly,
type,
value,
...props
}: UnknownFieldProps) {
return (
<div {...filterDOMProps(props)}>
<LabelField label={label} id={id} required={props.required} />
<div className={`text-[var(--vscode-errorForeground)]`}>{l10n.t(LocalizationKey.fieldUnknown)}</div>
</div>
);
}
UnknownField.defaultProps = { type: 'text' };
export default connectField<UnknownFieldProps>(UnknownField, { kind: 'leaf' });

View File

@@ -2,6 +2,7 @@ import { ValidatedForm } from 'uniforms';
import BaseForm from './BaseForm';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function Validated(parent: any) {
class _ extends ValidatedForm.Validated(parent) {
static Validated = Validated;

View File

@@ -3,46 +3,46 @@ import { ContentType } from './../models/PanelSettings';
export const DEFAULT_CONTENT_TYPE_NAME = 'default';
export const DEFAULT_CONTENT_TYPE: ContentType = {
"name": "default",
"pageBundle": false,
"previewPath": null,
"fields": [
name: 'default',
pageBundle: false,
previewPath: null,
fields: [
{
"title": "Title",
"name": "title",
"type": "string"
title: 'Title',
name: 'title',
type: 'string'
},
{
"title": "Description",
"name": "description",
"type": "string"
title: 'Description',
name: 'description',
type: 'string'
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
title: 'Publishing date',
name: 'date',
type: 'datetime',
default: '{{now}}',
isPublishDate: true
},
{
"title": "Content preview",
"name": "preview",
"type": "image"
title: 'Content preview',
name: 'preview',
type: 'image'
},
{
"title": "Is in draft",
"name": "draft",
"type": "draft"
title: 'Is in draft',
name: 'draft',
type: 'draft'
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
title: 'Tags',
name: 'tags',
type: 'tags'
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
title: 'Categories',
name: 'categories',
type: 'categories'
}
]
};
};

View File

@@ -0,0 +1,3 @@
export const DefaultFieldValues = {
faultyCustomPlaceholder: '<failed to process>'
};

View File

@@ -1,7 +1,7 @@
export const DefaultFields = {
PublishingDate: `date`,
LastModified: `lastmod`,
Description: `description`,
Title: `title`,
Slug: `slug`
};

View File

@@ -1,3 +1 @@
export const DEFAULT_FILE_TYPES = [".md", ".markdown", ".mdx"];
export const DEFAULT_FILE_TYPES = ['.md', '.markdown', '.mdx'];

Some files were not shown because too many files have changed in this diff Show More