• (cross-posting to this forum after a moderator referred me here)

    I’m trying to build a simple component that let’s the user create a list of tile links to other pages on the website.

    I’ve got the editor adding tiles to the list, with an image and title text etc. but I want to add a dropdown list of Pages to the editor so that user can easily pick which one to link to.

    How can I get the list of Pages from the back-end in the component’s .js file? It’s not processed by PHP so I can’t query for the data like I would to embed it in a page…

    Here’s the subpage-tiles.js component code if you need to see it:

    
    registerBlockType("mysite/subpage-tiles-block", {
      title: __("Subpage Tiles"),
      icon: "editor-insertmore", 
      category: "common", 
      keywords: [__("Subpage Tiles")],
    
      attributes: {
        tiles: {
          source: "query",
          default: [],
          selector: 'li',
          query: {
            index: {
              source: "text",
              selector: "span.tileIndex"
            },
            link: {
              source: "text",
              selector: ".tileLink"
            },
            image: {
              source: "attribute",
              selector: "img",
              attribute: "src"
            },
            title: {
              source: "text",
              selector: "h2.section-title"
            },
            text: {
              source: "text"
            }
          }
        }
      },
    
      edit: props => {
        const { tiles } = props.attributes;
    
        const tilesList = tiles.map(function(tile) {
          return (
            <li>
              <p>
                <span className="removeTile" onClick={() => {
                  const newTilesList = tilesList.filter(i => i.index != tile.index ).map(t => {
                    if (t.index > tile.index ) {
                      t.index -= 1;
                    }
                    return t;
                  });
                  props.setAttributes({
                    tilesList: newTilesList
                  });
                }}>&times;</span>
              </p>
              <div className="editTile">
                <div>
                  <MediaUpload
                    onSelect={media => {
                      const image = media.sizes.medium
                        ? media.sizes.medium.url
                        : media.url;
                      const newObject = Object.assign({}, tile, {
                        image: image
                      });
                      props.setAttributes({
                        tiles: [
                          ...tiles.filter(
                            item => item.index != tile.index
                          ),
                          newObject
                        ]
                      });
                    }}
                    type="image"
                    value={tile.image}
                    render={({ open }) =>
                      !!tile.image ? (
                        <div>
                          {props.isSelected && (
                            <div className="picture_actions">
                              <a
                                href="#"
                                onClick={() => {
                                  const newObject = Object.assign(
                                    {},
                                    tile,
                                    {
                                      image: null
                                    }
                                  );
                                  props.setAttributes({
                                    tilesList: [
                                      ...tilesList.filter(
                                        item => item.index != tile.index
                                      ),
                                      newObject
                                    ]
                                  });
                                }}
                              >
                                × Remove
                              </a>
                            </div>
                          )}
    
                          <div
                            className="image"
                            style={{
                              backgroundImage: <code>url(${tile.image})</code>
                            }}
                            onClick={open}
                          />
                        </div>
                      ) : (
                        <a
                          href="#"
                          className="image"
                          onClick={open}
                        >
                          Select Image
                        </a>
                      )
                    }
                  />
                </div>
                <div>
                  <PlainText
                    className="text-input"
                    placeholder="Title"
                    value={tile.title}
                    autoFocus
                    onChange={title => {
                      const newObject = Object.assign({}, tile, {
                        title: title
                      });
                      props.setAttributes({
                        tiles: [
                          ...tiles.filter(
                            item => item.index != tile.index
                          ),
                          newObject
                        ]
                      });
                    }}
                  />
                </div>
                <div>
                  <PlainText
                    className="text-input"
                    placeholder="Description"
                    value={tile.text}
                    autoFocus
                    onChange={text => {
                      const newObject = Object.assign({}, tile, {
                        text: text
                      });
                      props.setAttributes({
                        tiles: [
                          ...tiles.filter(
                            item => item.index != tile.index
                          ),
                          newObject
                        ]
                      });
                    }}
                  />
                </div>
              </div>
            </li>
          );
        });
    
        return (
          <div className="subpageTilesEditor">
            <ul>
              { tilesList }
            </ul>
            <button className="addTile" onClick={content => props.setAttributes({
              tiles: [
                ...props.attributes.tiles,
                {
                  index: props.attributes.tiles.length,
                  title: "",
                  text: "",
                  link: ""
                }
              ]
            })}><span>+</span></button>
          </div>
        );
      },
    
      save: props => {
        const { tiles } = props.attributes;
        
        const tilesList = tiles.map(function(tile) {
          const { link, image, title, text } = tile;
          const description = text ? <p>{text}</p> : null;
          return (
            <li>
              <a href={link} className="tileLink">
                <div className="image"><img src={image} alt={title} /></div>
                <div className="text">
                  <h2 className="section-title">{title}</h2>
                 { description }
                </div>
              </a>
              <a href={link} className="crosslink">More</a>
            </li>
          );
        });
        if (tilesList.length) {
          return (
            <ul className="subpage-tiles">
              {tilesList}
            </ul>
          )
        } 
        return (
          <p>No Subpage Tiles</p>
        );
      }
    });
    
    • This topic was modified 6 years, 3 months ago by robertqss. Reason: updated code
Viewing 1 replies (of 1 total)
  • I have the exact same question. You’d think it’d be easier to find documentation on this. Did you ever make any progress?

Viewing 1 replies (of 1 total)
  • The topic ‘Loading List of Pages into a Gutenberg Block’ is closed to new replies.