Skip to content

Commit

Permalink
Desktop: Remove template feature (replaced by template plugin)
Browse files Browse the repository at this point in the history
  • Loading branch information
laurent22 committed Aug 6, 2021
1 parent b060931 commit e9d5901
Show file tree
Hide file tree
Showing 15 changed files with 52 additions and 222 deletions.
3 changes: 0 additions & 3 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,6 @@ packages/app-desktop/gui/MainScreen/commands/renameTag.js.map
packages/app-desktop/gui/MainScreen/commands/search.d.ts
packages/app-desktop/gui/MainScreen/commands/search.js
packages/app-desktop/gui/MainScreen/commands/search.js.map
packages/app-desktop/gui/MainScreen/commands/selectTemplate.d.ts
packages/app-desktop/gui/MainScreen/commands/selectTemplate.js
packages/app-desktop/gui/MainScreen/commands/selectTemplate.js.map
packages/app-desktop/gui/MainScreen/commands/setTags.d.ts
packages/app-desktop/gui/MainScreen/commands/setTags.js
packages/app-desktop/gui/MainScreen/commands/setTags.js.map
Expand Down
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,6 @@ packages/app-desktop/gui/MainScreen/commands/renameTag.js.map
packages/app-desktop/gui/MainScreen/commands/search.d.ts
packages/app-desktop/gui/MainScreen/commands/search.js
packages/app-desktop/gui/MainScreen/commands/search.js.map
packages/app-desktop/gui/MainScreen/commands/selectTemplate.d.ts
packages/app-desktop/gui/MainScreen/commands/selectTemplate.js
packages/app-desktop/gui/MainScreen/commands/selectTemplate.js.map
packages/app-desktop/gui/MainScreen/commands/setTags.d.ts
packages/app-desktop/gui/MainScreen/commands/setTags.js
packages/app-desktop/gui/MainScreen/commands/setTags.js.map
Expand Down
24 changes: 0 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
- Supports multiple languages.
- External editor support - open notes in your favorite external editor with one click in Joplin.
- Extensible functionality through plugin and data APIs.
- Template support with data variables for auto creation of time & dates.
- Custom CSS support for customisation of both the rendered markdown and overall user interface.
- Customisable layout allows toggling, movement and sizing of various elements.
- Keyboard shortcuts are editable and allow binding of most Joplin commands with export/import functionality.
Expand Down Expand Up @@ -376,29 +375,6 @@ The whole UI can be customized by placing a custom editor style file in the prof

Important: userstyle.css and userchrome.css are provided for your convenience, but they are advanced settings, and styles you define may break from one version to the next. If you want to use them, please know that it might require regular development work from you to keep them working. The Joplin team cannot make a commitment to keep the application HTML structure stable.

# Note templates

In the **desktop app**, templates can be used to create new notes or to insert into existing ones by adding a template file to the `templates` directory (File > Templates). For example creating the file `hours.md` in the `templates` directory with the contents:

```markdown
Date: {{date}}
Hours:
Details:
```

Templates can then be inserted from the menu (File->Templates).

The currently supported template variables are:

| Variable | Description | Example |
| --- | --- | --- |
| `{{date}}` | Today's date formatted based on the settings format | 2019-01-01 |
| `{{time}}` | Current time formatted based on the settings format | 13:00 |
| `{{datetime}}` | Current date and time formatted based on the settings format | 01/01/19 1:00 PM |
| `{{#custom_datetime}}` | Current date and/or time formatted based on a supplied string (using [moment.js](https://momentjs.com/) formatting) | `{{#custom_datetime}}M d{{/custom_datetime}}` |
| `{{bowm}}` | Date of the beginning of the week (when week starts on Monday) based on the settings format | |
| `{{bows}}` | Date of the beginning of the week (when week starts on Sunday) based on the settings format | |

# Plugins

The **desktop app** has the ability to extend beyond its standard functionality by the way of plugins. These plugins adhere to the Joplin plugin API and can be installed & configured within the application via the `Plugins` page in the Configuration screen. This menu allows the manual installation of the plugin using the single 'Joplin Plugin Archive' (*.jpl) file. Once the application is reloaded the plugins will appear within the plugins menu where they can be toggled on/off or removed entirely.
Expand Down
33 changes: 22 additions & 11 deletions packages/app-desktop/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const Menu = bridge().Menu;
const PluginManager = require('@joplin/lib/services/PluginManager');
import RevisionService from '@joplin/lib/services/RevisionService';
import MigrationService from '@joplin/lib/services/MigrationService';
const TemplateUtils = require('@joplin/lib/TemplateUtils');
import { loadCustomCss, injectCustomStyles } from '@joplin/lib/CssUtils';
// import populateDatabase from '@joplin/lib/services/debug/populateDatabase';

Expand All @@ -62,7 +61,6 @@ const commands = [
require('./gui/MainScreen/commands/renameFolder'),
require('./gui/MainScreen/commands/renameTag'),
require('./gui/MainScreen/commands/search'),
require('./gui/MainScreen/commands/selectTemplate'),
require('./gui/MainScreen/commands/setTags'),
require('./gui/MainScreen/commands/showModalMessage'),
require('./gui/MainScreen/commands/showNoteContentProperties'),
Expand Down Expand Up @@ -538,6 +536,26 @@ class Application extends BaseApplication {
return cssString;
}

private async checkForLegacyTemplates() {
const templatesDir = `${Setting.value('profileDir')}/templates`;
if (await shim.fsDriver().exists(templatesDir)) {
try {
const files = await shim.fsDriver().readDirStats(templatesDir);
for (const file of files) {
if (file.path.endsWith('.md')) {
// There is atleast one template.
this.store().dispatch({
type: 'CONTAINS_LEGACY_TEMPLATES',
});
break;
}
}
} catch (error) {
reg.logger().error(`Failed to read templates directory: ${error}`);
}
}
}

private async initPluginService() {
const service = PluginService.instance();

Expand Down Expand Up @@ -617,8 +635,6 @@ class Application extends BaseApplication {

argv = await super.start(argv);

await fs.mkdirp(Setting.value('templateDir'), 0o755);

await this.applySettingsSideEffects();

if (Setting.value('sync.upgradeState') === Setting.SYNC_UPGRADE_STATE_MUST_DO) {
Expand Down Expand Up @@ -715,18 +731,13 @@ class Application extends BaseApplication {
css: cssString,
});

const templates = await TemplateUtils.loadTemplates(Setting.value('templateDir'));

this.store().dispatch({
type: 'TEMPLATE_UPDATE_ALL',
templates: templates,
});

this.store().dispatch({
type: 'NOTE_DEVTOOLS_SET',
value: Setting.value('flagOpenDevTools'),
});

await this.checkForLegacyTemplates();

// Note: Auto-update currently doesn't work in Linux: it downloads the update
// but then doesn't install it on exit.
if (shim.isWindows() || shim.isMac()) {
Expand Down
2 changes: 0 additions & 2 deletions packages/app-desktop/gui/KeymapConfig/utils/getLabel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const getLabel = (commandName: string): string => {
switch (commandName) {
case 'quit':
return _('Quit');
case 'insertTemplate':
return _('Insert template');
case 'zoomActualSize':
return _('Actual Size');
case 'gotoAnything':
Expand Down
24 changes: 21 additions & 3 deletions packages/app-desktop/gui/MainScreen/MainScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ interface Props {
showMissingMasterKeyMessage: boolean;
showNeedUpgradingMasterKeyMessage: boolean;
showShouldReencryptMessage: boolean;
showInstallTemplatesPlugin: boolean;
focusedField: string;
themeId: number;
settingEditorCodeView: boolean;
pluginsLegacy: any;
startupPluginsLoaded: boolean;
shareInvitations: ShareInvitation[];
isSafeMode: boolean;
needApiAuth: boolean;
}

interface ShareFolderDialogOptions {
Expand Down Expand Up @@ -123,7 +125,6 @@ const commands = [
require('./commands/renameFolder'),
require('./commands/renameTag'),
require('./commands/search'),
require('./commands/selectTemplate'),
require('./commands/setTags'),
require('./commands/showModalMessage'),
require('./commands/showNoteContentProperties'),
Expand Down Expand Up @@ -551,6 +552,16 @@ class MainScreenComponent extends React.Component<Props, State> {
});
};

const onViewPluginScreen = () => {
this.props.dispatch({
type: 'NAV_GO',
routeName: 'Config',
props: {
defaultSection: 'plugins',
},
});
};

const onRestartAndUpgrade = async () => {
Setting.setValue('sync.upgradeState', Setting.SYNC_UPGRADE_STATE_MUST_DO);
await Setting.saveAll();
Expand Down Expand Up @@ -627,6 +638,12 @@ class MainScreenComponent extends React.Component<Props, State> {
_('Set the password'),
onViewEncryptionConfigScreen
);
} else if (this.props.showInstallTemplatesPlugin) {
msg = this.renderNotificationMessage(
'The template feature has been moved to a plugin called "Templates".',
'Install plugin',
onViewPluginScreen
);
}

return (
Expand All @@ -638,7 +655,7 @@ class MainScreenComponent extends React.Component<Props, State> {

messageBoxVisible(props: Props = null) {
if (!props) props = this.props;
return props.hasDisabledSyncItems || props.showMissingMasterKeyMessage || props.showNeedUpgradingMasterKeyMessage || props.showShouldReencryptMessage || props.hasDisabledEncryptionItems || this.props.shouldUpgradeSyncTarget || props.isSafeMode || this.showShareInvitationNotification(props);
return props.hasDisabledSyncItems || props.showMissingMasterKeyMessage || props.showNeedUpgradingMasterKeyMessage || props.showShouldReencryptMessage || props.hasDisabledEncryptionItems || this.props.shouldUpgradeSyncTarget || props.isSafeMode || this.showShareInvitationNotification(props) || this.props.needApiAuth || this.props.showInstallTemplatesPlugin;
}

registerCommands() {
Expand Down Expand Up @@ -855,7 +872,6 @@ const mapStateToProps = (state: AppState) => {
selectedNoteId: state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null,
pluginsLegacy: state.pluginsLegacy,
plugins: state.pluginService.plugins,
templates: state.templates,
customCss: state.customCss,
editorNoteStatuses: state.editorNoteStatuses,
hasNotesBeingSaved: stateUtils.hasNotesBeingSaved(state),
Expand All @@ -865,6 +881,8 @@ const mapStateToProps = (state: AppState) => {
startupPluginsLoaded: state.startupPluginsLoaded,
shareInvitations: state.shareService.shareInvitations,
isSafeMode: state.settings.isSafeMode,
needApiAuth: state.needApiAuth,
showInstallTemplatesPlugin: state.hasLegacyTemplates && !state.pluginService.plugins['joplin.plugin.templates'],
};
};

Expand Down
5 changes: 1 addition & 4 deletions packages/app-desktop/gui/MainScreen/commands/newNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { utils, CommandRuntime, CommandDeclaration, CommandContext } from '@jopl
import { _ } from '@joplin/lib/locale';
import Setting from '@joplin/lib/models/Setting';
import Note from '@joplin/lib/models/Note';
const TemplateUtils = require('@joplin/lib/TemplateUtils');

export const declaration: CommandDeclaration = {
name: 'newNote',
Expand All @@ -12,12 +11,10 @@ export const declaration: CommandDeclaration = {

export const runtime = (): CommandRuntime => {
return {
execute: async (_context: CommandContext, template: string = null, isTodo: boolean = false) => {
execute: async (_context: CommandContext, body: string = '', isTodo: boolean = false) => {
const folderId = Setting.value('activeFolderId');
if (!folderId) return;

const body = template ? TemplateUtils.render(template) : '';

const defaultValues = Note.previewFieldsWithDefaultValues({ includeTimestamps: false });

let newNote = Object.assign({}, defaultValues, {
Expand Down
4 changes: 2 additions & 2 deletions packages/app-desktop/gui/MainScreen/commands/newTodo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export const declaration: CommandDeclaration = {

export const runtime = (): CommandRuntime => {
return {
execute: async (_context: CommandContext, template: string = null) => {
return CommandService.instance().execute('newNote', template, true);
execute: async (_context: CommandContext, body: string = '') => {
return CommandService.instance().execute('newNote', body, true);
},
enabledCondition: 'oneFolderSelected && !inConflictFolder',
};
Expand Down
33 changes: 0 additions & 33 deletions packages/app-desktop/gui/MainScreen/commands/selectTemplate.ts

This file was deleted.

47 changes: 0 additions & 47 deletions packages/app-desktop/gui/MenuBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const packageInfo = require('../packageInfo.js');
const { clipboard } = require('electron');
const Menu = bridge().Menu;
const PluginManager = require('@joplin/lib/services/PluginManager');
const TemplateUtils = require('@joplin/lib/TemplateUtils');

const menuUtils = new MenuUtils(CommandService.instance());

Expand Down Expand Up @@ -301,7 +300,6 @@ function useMenu(props: Props) {

const importItems = [];
const exportItems = [];
const templateItems: any[] = [];
const ioService = InteropService.instance();
const ioModules = ioService.modules();
for (let i = 0; i < ioModules.length; i++) {
Expand Down Expand Up @@ -366,39 +364,6 @@ function useMenu(props: Props) {
const newSubFolderItem = menuItemDic.newSubFolder;
const printItem = menuItemDic.print;

templateItems.push({
label: _('Create note from template'),
click: () => {
void CommandService.instance().execute('selectTemplate', 'note');
},
}, {
label: _('Create to-do from template'),
click: () => {
void CommandService.instance().execute('selectTemplate', 'todo');
},
}, {
label: _('Insert template'),
accelerator: keymapService.getAccelerator('insertTemplate'),
click: () => {
void CommandService.instance().execute('selectTemplate');
},
}, {
label: _('Open template directory'),
click: () => {
void bridge().openItem(Setting.value('templateDir'));
},
}, {
label: _('Refresh templates'),
click: async () => {
const templates = await TemplateUtils.loadTemplates(Setting.value('templateDir'));

props.dispatch({
type: 'TEMPLATE_UPDATE_ALL',
templates: templates,
});
},
});

let toolsItems: any[] = [];

// we need this workaround, because on macOS the menu is different
Expand Down Expand Up @@ -493,13 +458,6 @@ function useMenu(props: Props) {
{
type: 'separator',
visible: shim.isMac() ? false : true,
}, {
label: _('Templates'),
visible: shim.isMac() ? false : true,
submenu: templateItems,
}, {
type: 'separator',
visible: shim.isMac() ? false : true,
}, {
label: _('Import'),
visible: shim.isMac() ? false : true,
Expand Down Expand Up @@ -555,11 +513,6 @@ function useMenu(props: Props) {
selector: 'performClose:',
}, {
type: 'separator',
}, {
label: _('Templates'),
submenu: templateItems,
}, {
type: 'separator',
}, {
label: _('Import'),
submenu: importItems,
Expand Down
1 change: 0 additions & 1 deletion packages/lib/BaseApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,6 @@ export default class BaseApplication {

Setting.setConstant('env', initArgs.env);
Setting.setConstant('profileDir', profileDir);
Setting.setConstant('templateDir', `${profileDir}/templates`);
Setting.setConstant('resourceDirName', resourceDirName);
Setting.setConstant('resourceDir', resourceDir);
Setting.setConstant('tempDir', tempDir);
Expand Down
Loading

2 comments on commit e9d5901

@tessus
Copy link
Collaborator

@tessus tessus commented on e9d5901 Aug 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would help, if the plugin was actually in the repository (and thus can be installed via the Plugins screen.). ;-) Haha.

@laurent22
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's what we're discussing on Discord. We'll wait till Nishan has published the plugin before releasing the app.

Please sign in to comment.