Skip to content

Commit

Permalink
feedback fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
barthc committed Feb 24, 2019
1 parent ed3da48 commit 61abc02
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 32 deletions.
4 changes: 2 additions & 2 deletions dev-test/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ collections: # A list of collections the CMS should be able to edit
guidelines that are specific to a collection.
folder: '_posts'
slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
slug_field: 'slug'
create: true # Allow users to create new documents in this collection
fields: # The fields each document in this collection have
- { label: 'Title', name: 'title', widget: 'string', tagname: 'h1' }
- { label: 'Slug', name: 'slug', widget: 'string', tagname: 'h1' }
- {
label: 'Publish Date',
name: 'date',
Expand All @@ -41,9 +39,11 @@ collections: # A list of collections the CMS should be able to edit
- name: 'faq' # Used in routes, ie.: /admin/collections/:slug/edit
label: 'FAQ' # Used in the UI
folder: '_faqs'
slug_field: 'slug'
create: true # Allow users to create new documents in this collection
fields: # The fields each document in this collection have
- { label: 'Question', name: 'title', widget: 'string', tagname: 'h1' }
- { label: 'Slug', name: 'slug', widget: 'string', tagname: 'h1' }
- { label: 'Answer', name: 'body', widget: 'markdown' }

- name: 'settings'
Expand Down
35 changes: 12 additions & 23 deletions packages/netlify-cms-core/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ function compileSlug(template, date, identifier = '', data = Map(), processor) {
}
}

export function slugFormatter(collection, entryData, slugConfig) {
function slugFormatter(collection, entryData, slugConfig) {
const template = collection.get('slug') || '{{slug}}';

const identifier = entryData.get(selectIdentifier(collection));
Expand All @@ -129,19 +129,6 @@ export function slugFormatter(collection, entryData, slugConfig) {
return processSlug(template, new Date(), identifier, entryData);
}

const sanitizeEntrySlug = (slug, slugConfig) => {
return sanitizeSlug(
slug
// Convert slug to lower-case
.toLocaleLowerCase()
// Remove single quotes.
.replace(/[']/g, '')
// Replace periods with dashes.
.replace(/[.]/g, '-'),
slugConfig,
);
};

const commitMessageTemplates = Map({
create: 'Create {{collection}} “{{slug}}”',
update: 'Update {{collection}} “{{slug}}”',
Expand Down Expand Up @@ -347,8 +334,9 @@ class Backend {
}

async generateUniqueSlug(collection, slug, slugConfig, unavailableSlugs, availableSlugs = []) {
const sanitizeEntrySlug = flow([prepareSlug, partialRight(sanitizeSlug, slugConfig)]);
let i = 1;
let sanitizedSlug = sanitizeEntrySlug(slug, slugConfig);
let sanitizedSlug = sanitizeEntrySlug(slug);
let uniqueSlug = sanitizedSlug;

// Return if slug is the same as the current entry or parent slug.
Expand All @@ -359,7 +347,7 @@ class Backend {
unavailableSlugs.includes(uniqueSlug) ||
(await this.entryExist(collection, selectEntryPath(collection, uniqueSlug), uniqueSlug))
) {
uniqueSlug = sanitizeEntrySlug(`${sanitizedSlug} ${i++}`, slugConfig);
uniqueSlug = sanitizeEntrySlug(`${sanitizedSlug} ${i++}`);
}
return uniqueSlug;
}
Expand Down Expand Up @@ -646,14 +634,15 @@ class Backend {
if (!selectAllowNewEntries(collection)) {
throw new Error('Not allowed to create new entries in this collection');
}
const autoSlug = await this.getSlug(
collection,
entryDraft.getIn(['entry', 'data']),
config.get('slug'),
unavailableSlugs,
);
const slug = selectedSlug || autoSlug;

const slug =
selectedSlug ||
(await this.getSlug(
collection,
entryDraft.getIn(['entry', 'data']),
config.get('slug'),
unavailableSlugs
));
const path = selectEntryPath(collection, slug);
entryObj = {
path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ const EntryCard = ({
const slug = entry.get('slug');
const title = label || entry.getIn(['data', inferedFields.titleField]);
const childEntry = unpublishedChildEntry(collection.get('name'), slug);
const selectedSlug = (childEntry && childEntry.get('slug')) || slug;
const path = `/collections/${collection.get('name')}/entries/${selectedSlug}`;
const entrySlug = (childEntry && childEntry.get('slug')) || slug;
const path = `/collections/${collection.get('name')}/entries/${entrySlug}`;
let image = entry.getIn(['data', inferedFields.imageField]);
image = resolvePath(image, publicFolder);
if (image) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,14 @@ class EditorControl extends React.Component {
const entryData = entry.get('data');
const unavailableSlugs = boundSelectSlugs(collection.get('name'));
const availableSlugs = [entry.get('slug'), entry.getIn(['metaData', 'parentSlug'])];
const indentifierField = collection && selectIdentifier(collection);
const identifierField = collection && selectIdentifier(collection);
const slugField = collection && selectSlugField(collection);
const slugValue = entry.getIn(['data', slugField]);
const backend = currentBackend(config);

this.setState({ styleActive: false });

if (fieldName == indentifierField && value && !slugValue && collection) {
if (fieldName == identifierField && value && !slugValue && collection) {
onChange(slugField, await backend.getSlug(collection, entryData, config, unavailableSlugs));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export default class ControlPane extends React.Component {
onValidate={onValidate}
processControlRef={this.controlRef.bind(this)}
controlRef={this.controlRef}
unavailableSlugs={unavailableSlugs}
isNewEntry={isNewEntry}
/>
),
Expand Down
5 changes: 3 additions & 2 deletions packages/netlify-cms-core/src/reducers/editorialWorkflow.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Map, List, fromJS } from 'immutable';
import { startsWith } from 'lodash';
import { EDITORIAL_WORKFLOW } from 'Constants/publishModes';
import {
UNPUBLISHED_ENTRY_REQUEST,
Expand Down Expand Up @@ -143,15 +144,15 @@ export const selectUnpublishedEntryByParentSlug = (state, collection, slug) => {
if (!state.get('entities')) return null;
return state
.get('entities')
.filter((v, k) => k.includes(collection))
.filter((v, k) => startsWith(k, `${collection}.`))
.find(entry => entry.getIn(['metaData', 'parentSlug']) === slug);
};

export const selectUnpublishedSlugEntriesByCollection = (state, collection) => {
if (!state.get('entities')) return null;
return state
.get('entities')
.filter((v, k) => k.includes(collection))
.filter((v, k) => startsWith(k, `${collection}.`))
.map(entry => entry.get('slug'))
.valueSeq();
};
Expand Down
21 changes: 21 additions & 0 deletions website/content/docs/beta-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,27 @@ sections:
- images/image06.png
```

## Slug Customization
This feature makes it possible to edit slug entries. To enable this feature, add a config collection setting `slug_field` with the value pointing to the name of a field widget preferable a `string` widget, this widget will be used as the slug field.

The value of the slug field is not saved in the frontmatter. The slug value is used internally by the CMS for entry navigation, to generate entry filename, etc.
And If there is a slug change for any published or unpublished entry, a new slug entry is created, and the old slug entry is deleted.

### Example Configuration
```yaml
collections:
- name: "blog"
label: "Blog"
folder: "content/blog"
create: true
slug_field: 'slug'
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
fields:
- { label: "Title", name: "title", widget: "string" }
- { label: "Slug", name: "slug", widget: "string" }
- { label: 'Body', name: 'body', widget: 'markdown' }
```

## Custom Mount Element
Netlify CMS always creates its own DOM element for mounting the application, which means it always takes over the entire page, and is generally inflexible if you're trying to do something creative, like injecting it into a shared context.

Expand Down

0 comments on commit 61abc02

Please sign in to comment.