Grav-plugin-admin: Custom add page options

Created on 13 Apr 2017  ·  16Comments  ·  Source: getgrav/grav-plugin-admin

As I explained in getgrav/grav#421, it would be great to have the possibility to add custom page types based on blueprints in the Add Page Menu.

For example the menu by default has these choices:

  • Add Page
  • Add Folder
  • Add Modular
    I'd like to be able to add thins like:
    Add Blog Post
    Add Gallery
    Add Other special page type.

These options would automatically set things up so that a page for example would be created inside the blog/ directory with an "Item" page template in order to create a blog post etc..

This would be a very useful feature, especially when handing the site to clients who would not have to worry about page templates and folder structure.

enhancement

Most helpful comment

I think we could make a configuration for this.
I have this in my local version if we can agree on the configuration structure I can refactor it into a PR.

By default, it uses the template used by Add Page.

admin.yaml

add_modals:
  post:
    label: Add Post
    blueprint: admin/pages/new_post
    template: custom_template
    link_classes: some_class
    modal_classes: some_modal_class
    with:
      some_data: for the template
    show_in: dropdown
  image:
    label: Add Image
    blueprint: admin/pages/new_image
    show_in: bar

An example blueprint. On my blog I have more than 1 authors so with the getNewPostRoute I can generate a route for the user, for example for my account it generates: "/dave/posts"

new_post.yaml

form:
  validation: loose
  fields:
    section:
        type: section
        title: Add Post

    title:
      type: text
      label: Post Title
      validate:
        required: true

    folder:
      type: hidden

    route:
      type: hidden
      data-default@: '\Grav\Plugin\MyPlugin::getNewPostRoute'

    name:
      type: hidden
      default: 'post'

    visible:
      type: hidden
      default: ''

    blueprint:
      type: blueprint

Some images

screenshot from 2017-04-26 11-45-05
screenshot from 2017-04-26 11-45-26

All 16 comments

I would need this soon for a client
do you have any indications on how I could implement this myself?

Well when you tell a client to add a page, all they gotta do is select a Template for the right thing. If you set up the blog, the gallery, etc it will be just as easy. However, if you really wanted to add buttons, just duplicate the add page button but put the field template preselected and hidden (if you so wish)

@ricardo118 I wish i could simply tell them to select the right template and the right folder, unfortunately because of the way the modal is currently designed, the selection box of the folder lists all the pages of the site, which is problematic because in order to find the right folder they need to scroll through potentially hundreds of pages. Hence the predefined modals.

I was hoping for a more elegant solution to implement this than simply copy & pasting the modals, and directly editing the plugin's files. (Because of updates)
I did try to do it though, but I run into problems when trying to specify the default value of select boxes: Strangely enough I never get the right option by default.

Is there any way to extend the admin plugin without changing its code to do what I want ?

I think we could make a configuration for this.
I have this in my local version if we can agree on the configuration structure I can refactor it into a PR.

By default, it uses the template used by Add Page.

admin.yaml

add_modals:
  post:
    label: Add Post
    blueprint: admin/pages/new_post
    template: custom_template
    link_classes: some_class
    modal_classes: some_modal_class
    with:
      some_data: for the template
    show_in: dropdown
  image:
    label: Add Image
    blueprint: admin/pages/new_image
    show_in: bar

An example blueprint. On my blog I have more than 1 authors so with the getNewPostRoute I can generate a route for the user, for example for my account it generates: "/dave/posts"

new_post.yaml

form:
  validation: loose
  fields:
    section:
        type: section
        title: Add Post

    title:
      type: text
      label: Post Title
      validate:
        required: true

    folder:
      type: hidden

    route:
      type: hidden
      data-default@: '\Grav\Plugin\MyPlugin::getNewPostRoute'

    name:
      type: hidden
      default: 'post'

    visible:
      type: hidden
      default: ''

    blueprint:
      type: blueprint

Some images

screenshot from 2017-04-26 11-45-05
screenshot from 2017-04-26 11-45-26

@david-szabo97 This is precisely what I had in mind. Great job! This configuration looks pretty sensible to me. I especially like that show_in: bar|dropdown, neat. How do you handle the folder name part ?

While waiting for the team to offer its impression for a PR, do you have a version of your code somewhere online ?

@fireraccoon I have edited the javascript part of the add page to auto-slugify the title. Just as it would do when you create a page. Though in this case you can't see the folder because it's hidden. But it would do the same when you create a normal page, just simply copy the slugified title into the folder text box.

Because it puts the new page (folder) into the route, you can specify custom route, just as I did data-default@: '\Grav\Plugin\MyPlugin::getNewPostRoute and in the end you will have the same effect. ($route . $folder)

I don't have it anywhere available yet, but I can upload it for you if you want.

@david-szabo97 Ok I see! I was wondering if you did it the JS way or with some kind of post form processing hook. Yes I would love to see it if you have the time thanks!

@fireraccoon It could be done with an event hook but JS way seems better.
I attached a zip file, just replace your plugins/admin with this admin folder.
You can lookup the changes I made by searching for * MessedCode (It's my upcoming blog based on Grav)
I had some other changes in it so I hope I removed everything else and it works fine.

The code you will find in the admin.min.js is copied from the add.js. It's just a way I can avoid repacking the whole JS project.

We have a couple of users on my blog so I had to make many changes to make posting comfortable for everyone. This is one of the changes we need badly.
admin.zip

@david-szabo97 Thank you soo much! You saved my day. I managed to get it working with the latest version quite easily. Works like a charm. I think this is quite an important use case, and I really hope to see it integrated in the plugin soon. Plus the changes are very simple.

A PR would be good. I would prefer if were not relying on JS to do however.

@rhukster, I would like to pass arbitrary frontmatter data from the modal. This seems not to work at the moment. Could you suggest where I should look in the code base to address that? Am I misguided as to the purpose of these modals?

form:
  validation: loose
  fields:
    section:
      type: section
      title: Add Fancy Page

    title:
      type: text
      label: Title

    a_custom_attribute:
      type: text
      default: dummy
      label: Won't pre-populate the corresponding field

    header.another_custom_attr:
      type: text
      label: Neither will this
      validate:
        required: true

@k8n
I can confirm that it does not work as one would expect. Right now only the directory and template fields work, but all the custom front matter attributes won't be populated.

I'm not sure how the with field passes data onto the actual page it generates. I've made a custom modal; as below - trying to set fields in the header, but nothing appears in the header, nor are any errors lodged?

```form:
validation: loose
fields:
section:
type: section
title: Add Media Item

title:
  type: text
  label: Media Item Title
  validate:
    required: true

header.article_hyperlink:
  type: text
  label: Article Hyperlink (URL)
  validate:
    required: true
    type: url
header.article_date:
  type: date
  label: Article Date
  validate:
    required: true
header.article_blurb:
  type: textarea
  label: Article Blurb

folder:
  type: hidden
  default: '@slugify-title'

route:
  type: hidden
  default: /media

name:
  type: hidden
  default: 'media-item'

blueprint:
  type: blueprint

```

The modal appears, and creates the content, but none of the data from the fields is passed along?

@sjclark, as I said in my comment above yours, currently passing the data from the modal is not implemented, I checked with Grav Dev Team.

Hopefully, someone will make a PR soon for this!

+1 on this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  ·  6Comments

coolemur picture coolemur  ·  3Comments

CoDanny picture CoDanny  ·  3Comments

orasik picture orasik  ·  6Comments

dimayakovlev picture dimayakovlev  ·  5Comments