Community

MODX React CMP and Restful API setup

This video explores the use of #React in MODX Custom Manager Pages, breaking the constraints of ExtJS. We also explore setting up modx as a #headless #cms returning json data for resources and custom packages.

Creating Custom Manager Pages in MODX:
https://docs.modx.com/revolution/2.x/developing-in-modx/advanced-development/custom-manager-pages/custom-manager-pages-in-2.3

Developing Restful API’s in MODX:
https://docs.modx.org/current/en/extending-modx/developing-restful-api

Install webpack, babel + loaders command:
https://pastebin.com/wHMSBXAf

webpack.config.js:
https://pastebin.com/MRAa8iB6

4 Likes

@lkfranklin Great stuff! I plan on using React in my next Extra.
How would you deal with having the css and js files under assets/components/myextra/?
Unless I missed something I think the current setup wouldn’t work with a moved core.

Also, would you recommend a particular React grid system that might be a good replacement for the ExtJS grid?

Thanks @digitalpenguin react-table is really powerful and you can do a lot of things with it and really well documented.

Here’s an example (loads more on the above link):

So long as you scope to the paths correctly it should be fine? ie: getOption('assets_path') instead of getOption('core_path')

1 Like

Cheers I’ll check it out!
I had a feeling there would be issues with things outside the main app directory but if not that’s great!

Thanks let me know how you get on, but I think it should be fine :slight_smile:

I wanted to keep it simple for this video so some things may not be setup as well as they should be so just use it as a guide. In the next video I’ll create a working example of both front end/back end including with the above table package.

1 Like

Few Questions -

1. What if I want to fetch only 5 child resources from a tree or only 5 parent resources ? Suppose from Collections Extra… I have two Collections containers as blog categories, I want to get only 5 or 10 articles from that category … how to get it in api ?

2. How to get tv value like image in json ? Suppose I want to fetch an image tv which is set as featured image or post thumbnail. How can i get it for every resource ?

3. How to get list of menu names ? Suppose im creating an app and want to fetch list of navigation items names for sidebar of my app. How can I get only names of resources ?

Please make another video for endpoints. Specially for Image and other TVs and Snippets.

Thank you!

i’ll try to answer your questions when I circle back and create the react blog manager page your requested. my knowledge is pretty limited though :wink:

1 Like

:slight_smile:. Waiting with high hopes…
Any timeline?? When will you create new video??

I usually only get an hour or two free at the weekend to do the videos. I need to quickly finish off the tensorflow one and then either continue with the Fred series or do this one… in short im not sure but probably a few weeks off yet

1 Like

Ok will wait.
but if you can help here about how to get only specific number of resources then it will be very good for me.
I just played with your code from an old post from Facebook group and learned what I wanted to learn. Just dont know how to get only few resources.
I want pagination in json call …
Like wordpress do this way -

Any API response which contains multiple resources supports several common query parameters to handle paging through the response data:

?page=: specify the page of results to return.
    For example, /wp/v2/posts?page=2 is the second page of posts results
    By retrieving /wp/v2/posts, then /wp/v2/posts?page=2, and so on, you may access every available post through the API, one page at a time.
?per_page=: specify the number of records to return in one request, specified as an integer from 1 to 100.
    For example, /wp/v2/posts?per_page=1 will return only the first post in the collection
?offset=: specify an arbitrary offset at which to start retrieving posts
    For example, /wp/v2/posts?offset=6 will use the default number of posts per page, but start at the 6th post in the collection
    ?per_page=5&page=4 is equivalent to ?per_page=5&offset=15

I want something like this. Pagination.

You’ll need to do that with PHP within the endpoint.

Or you could even use getPage or pdoPage within a $modx->runSnippet() in the endpoint then just exit with the results e.g.

header('Content-Type: application/json;charset=utf-8');
exit(json_encode($output));
1 Like

I am not getting it … Can you help me with my code ?
Here is my full code -

class MyControllerResources extends modRestController {
   public $classKey = 'modResource';
  // public $defaultSortField = 'sortorder';
   public $defaultSortDirection = 'ASC';
  // ['tvvalue'] = $object->getTVValue('tvname');
   public $defaultSortField = 'id';
  // public $defaultSortDirection = 'DESC';
  public function prepareListObject(xPDOObject $object) {
   
         $data = array();

               $data['pagetitle'] = $object->pagetitle;
               $data['content'] = $object->content;
               $data['introtext'] = $object->introtext;
               $data['longtitle'] = $object->longtitle;
               $data['description'] = $object->description;
               $data['featuredimage'] = $object->getTVValue('myimagetv');
               $data['kitnelog'] = $object->getTVValue('mysimpletexttv');
               
         return $data;
             }

             public function read($id) {
               if (empty($id)) {
                   return $this->failure($this->modx->lexicon('rest.err_field_ns',array(
                       'field' => $this->primaryKeyField,
                       )));
               }
            // @var xPDOObject $object 
       
               $c = $this->getPrimaryKeyCriteria($id);
               $this->object = $this->modx->getObject($this->classKey,$c);
               if (empty($this->object)) {
                   return $this->failure($this->modx->lexicon('rest.err_obj_nf',array(
                       'class_key' => $this->classKey,
                       )));
               }
               $objectArray = $this->object->toArray();
               $objectArray += array(
                   'featuredimage' => $this->object->getTVValue('myimagetv'),
                   'kitnelog' => $this->object->getTVValue('mysimpletexttv')
                   );
        
               unset(
                   $objectArray['alias'],
                   $objectArray['alias_visible'],
                   $objectArray['parent'],
                   $objectArray['type'],
                   $objectArray['contentType'],
                   $objectArray['link_attributes'],
                   $objectArray['published'],
                   $objectArray['pub_date'],
                   $objectArray['isfolder'],
                  // $objectArray['introtext'],
                   $objectArray['richtext'],
                   $objectArray['template'],
                   $objectArray['menuindex'],
                   $objectArray['searchable'],
                   $objectArray['cacheable'],
                   $objectArray['createdby'],
                   $objectArray['createdon'],
                   $objectArray['editedby'],
                   $objectArray['editedon'],
                   $objectArray['deleted'],
                   $objectArray['deletedon'],
                   $objectArray['deletedby'],
                   $objectArray['published'],
                   $objectArray['unpub_date'],
                   $objectArray['publishedon'],
                   $objectArray['publishedby'],
                   $objectArray['menutitle'],
                   $objectArray['donthit'],
                   $objectArray['privateweb'],
                   $objectArray['privatemgr'],
                   $objectArray['content_dispo'],
                   $objectArray['hidemenu'],
                   $objectArray['class_key'],
                   $objectArray['context_key'],
                   $objectArray['content_type'],
                   $objectArray['uri'],
                   $objectArray['uri_override'],
                   $objectArray['hide_children_in_tree'],
                   $objectArray['show_in_tree'],
                   $objectArray['properties']
                   );
        
               $afterRead = $this->afterRead($objectArray);
               if ($afterRead !== true && $afterRead !== null) {
                   return $this->failure($afterRead === false ? $this->errorMessage : $afterRead);
               }
        
               return $this->success('',$objectArray);
           }
          }

Probably better if you create a new topic for your issue rather than posting here, @mayanktaker.

Sure thing. I wan about to create a new topic but then I thought about SEO and I thought that when someone read this topic, they will get more help with questions and answers about REST api here instead of searching again and again for same thing.
But I respect your suggestion and going to create a new topic for this. :slight_smile: