# Best practice for creating nodes

**URL:** <https://discuss.prosemirror.net/t/best-practice-for-creating-nodes/1404>\
**Category:** Uncategorized\
**Created:** [June 27, 2018, 6:07am UTC](https://discuss.prosemirror.net/t/best-practice-for-creating-nodes/1404 "2018-06-27T06:07:25Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![bbalban](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/bbalban/32/638_2.png) [@bbalban](https://discuss.prosemirror.net/u/bbalban)\
**Post date:** [June 28, 2018, 7:18am UTC](https://discuss.prosemirror.net/t/best-practice-for-creating-nodes/1404/3 "2018-06-28T07:18:15Z")

</div>

Thank you, this worked great. I have one more problem with deleting nodes.

My current document structure:

```auto
<section>
  <p>text

<image_section>
  <image_block>
    <img>
  <caption>

<section>
  <p>

```

When using backspace in last `<p>` node, it used to join the `<p>` backwards into image\_section [as described here](https://discuss.prosemirror.net/t/backspace-and-enter-and-delete-i-guess/57/1). so I constrained image\_section content to be:

```auto
  image_section: {
    content: "(image_block){1}(caption){1}",
    group: "container",
    defining: true, /* Don't know what this is. */
    parseDOM: [{tag: "div.section_content.editor-image"}],
    toDOM(node) { return ["div", {class: "section_content editor-image"}, 0] }
  },

```

I also modified image node to be not inline and as a leaf node, as I did not want it to be treated as text.

If I press backspace, the cursor moves back into caption as expected. When caption is empty, it deletes the `<img>` but not image\_section, image\_block or caption nodes. These nodes cannot be deleted at the moment.

How would you define your nodes to delete whole \<image\_section\> with backspace, when caption is empty?

My nodes for reference:

```auto
  doc: {
    content: "(section|image_section)+"
  },

  image_section: {
    content: "(image_block){1}(caption){1}",
    group: "container",
    defining: true, /* Don't know what this is. */
    parseDOM: [{tag: "div.section_content.editor-image"}],
    toDOM(node) { return ["div", {class: "section_content editor-image"}, 0] }
  },

  // :: NodeSpec Wrapper tag around images.
  image_block: {
    content: "image{1}",
    group: "block",
    defining: true,
    parseDOM: [{ tag: "div.imageblock" }],
    toDOM() { return ["div", { class: "imageblock"}, 0] }
  },

  // :: NodeSpec An inline image (`<img>`) node. Supports `src`,
  // `alt`, and `href` attributes. The latter two default to the empty
  // string.
  image: {
    inline: false,
    isLeaf: true,
    attrs: {
      src: { default: null},
      alt: {default: null},
      title: {default: null}
    },
    /*group: "",*/
    /*draggable: true,*/
    parseDOM: [{tag: "img[src]", getAttrs(dom) {
      return {
        src: dom.getAttribute("src"),
        title: dom.getAttribute("title"),
        alt: dom.getAttribute("alt")
      }
    }}],
    toDOM(node) { return ["img", node.attrs] }
  },

 // A special paragraph that goes under images only.
  caption: {
    content: "inline*",
    group: "block",
    attrs: { class: {default: "caption"}},
    parseDOM: [{tag: "p.caption"}],
    toDOM(node) { 
      node.attrs["data-placeholder"] = "Add caption here.";
      return ["p", node.attrs, 0] 
    }
  },

```

Alternatively I could define a tooltip on the image and a special delete command, but I’d love to have your advice first.

Thank you, Bahadir

---

_[View the full topic](https://discuss.prosemirror.net/t/best-practice-for-creating-nodes/1404)._
