Jump to content

Incorporating vue with Processwire


louisstephens
 Share

Recommended Posts

So I have been diving into vue.js lately, and I am really impressed. I thought it could be perfect for an internal dashboard using PageQuerry boss to retrieve the data. However, I do have a few questions that someone might be able to guide me with before I fully commit. 

1. Is it even possible to bootstrap pw into a vue app?

2. How would it be possible to handle user registration/logins without actually having to mirror the users on pw in another service? 

3. I know I could easily use an iframe in a modal to handle page editing (as I have done it inside of pw before), but would this be the best solution?

Link to comment
Share on other sites

Just very quickly...

  1. Not sure, but why would you want to? It's enough if you sit down and think about what kind of data you'll gonna need from PW. Then create appropriate JSON files that deliver raw data to your Vue.js app. You don't even need something like PageQueryBoss for that. Send a request from Vue to PW, do your usual $pages->find() or whatever, create an array, do json_encode(), set appropriate JSON-headers, and that's it.
  2. Frankly, haven't tried that. But you don't have to "mirror" PW users in your Vue.js app. Just send requests with credentials to PW, and return true/false and maybe add an HTTP header token for logins. For registrations, it's going to be a little more coding, but with PW's API, it shouldn't be too hard.
  3. Do you want to render/show PW's native page-edit view within that modal, or do you plan to re-create the whole page-edit functionality in Vue? I'd steer away from the latter, cause you'd be re-creating the proverbial wheel.

 

  • Like 1
Link to comment
Share on other sites

Thanks dragan. In my head I just assumed that I would need to bootstrap it. I tried doing a simple ajax request like {{info}} is in the actual markup for the controller:

import axios from 'axios';

export default {
  name: 'Api',
  data () {
    return {
      info: null
    }
  },
  mounted () {
	axios
		.get('http://localhost:8888/development/sites/test/ajax-actions/test-api')
		.then(response => (this.info = response))
  }
}

And in my processwire ajax-actions.php  file:

<?php
else if ($config->ajax && $input->urlSegment1 == 'test-api') {
    $searchResults = $page->find("template=basic");
    $json = array();
    foreach($searchResults as $search){
        $json[] = array(
          'title' => $seach->title,
         );
    }
    echo json_encode($json);
}
?>

 

I guess I have two issues with this setup. 

1. In my console on my vue app, I get No 'Access-Control-Allow-Origin' header is present on the requested resource

2. And secondly, data that is output seems to be just "

"{ "data": "", "status": 200, "statusText": "OK", "headers": { "pragma": "no-cache", "content-type": "text/html; charset=utf-8", "cache-control": "no-store, no-cache, must-revalidate", "expires": "Thu, 19 Nov 1981 08:52:00 GMT" }, "config": { "transformRequest": {}, "transformResponse": {}, "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "headers": { "Accept": "application/json, text/plain, */*" }, "method": "get", "url": "http://localhost:8888/development/sites/test/ajax-actions/test-api" }, "request": {} }

 

What have I missed? Sorry, I am still trying to figure this all out.

Link to comment
Share on other sites

You have several typos in your code. 

  $searchResults = $pages->find("template=product")->explode(function($item, $i) {
      return [
            'title' =>  $item . ' - ' . $i
          ];
  });

 d(wireEncodeJSON($searchResults));

 

  • Like 1
Link to comment
Share on other sites

Thanks zeka, I was playing around with your suggestion, but if I look at the console, "data" is completely empty. I can out put the "json" by just encoding it, but it isnt passing anything actual to the app. Ill keep searching.

{ "data": "", "status": 200, "statusText": "OK", "headers": { "pragma": "no-cache", "content-type": "text/html; charset=utf-8", "cache-control": "no-store, no-cache, must-revalidate", "expires": "Thu, 19 Nov 1981 08:52:00 GMT" }, "config": { "transformRequest": {}, "transformResponse": {}, "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "headers": { "Accept": "application/json, text/plain, */*" }, "method": "get", "url": "http://1ocalhost:8888/development/sites/test/ajax-actions/test-api/" }, "request": {} }

 

Link to comment
Share on other sites

A few things...

With the axios call, try querying the relative and not the absolute url. Also, take note of the trailing slash on the url, sometimes that can trip you up depending on your template settings. Finally, you probably don't need to set the entire response to your Vue data object, with axios you are looking for response.data. 

axios.get('/ajax-actions/test-api/).then(response => (this.info = response.data));

If you need to keep the full absolute url, or if you are calling the api page from a different url, then look into CORS. Setting the header below on your template should be enough, depends on your setup (eg see this topic for issues with CORS when using procache).

<php
  header('Content-Type: application/json,charset=utf-8');
  header("access-control-allow-origin: *");
  //...
  ?>

 

  • Like 2
Link to comment
Share on other sites

Thanks @mke and everyone else for the help. I got the "content-type" in the headers to return as application/json now. It's odd to me that I can call response.headers and return all the header information for the call, but the data is just blank. I looked at the json on the the actual page and it is being returned as:

[{"title":"Development","summary":"Epic cheeseburgers come in all kinds of manifestations, but we want them in and around our mouth no matter what. Slide those smashed patties with the gently caramelized meat fat between a toasted brioche bun and pass it over. You fall in love with the cheeseburger itself but the journey ain\u2019t half bad either.","body":"
They\u2019re the childhood friend that knows your highest highs and lowest lows. They\u2019ve been with you through thick and thin and they\u2019re the best at keeping secrets. Whether it\u2019s dressed up or informal, cheeseburgers have your back.<\/p>\n\n

Sometimes we lose sight of what really matters in life. There\u2019s something to be said for a gourmet brie and truffle burger paired with parmesan frites, but don\u2019t let that make you forget about the ol\u2019 faithful with American cheddar and a squishy bun. Lettuce remind you that cheeseburgers come in all forms - bun intended.<\/p>\n\n

Pop quiz: what\u2019s the greatest thing to happen to your mind, body, and soul in recent history? A cheeseburger, obviously. Cheeseburgers know that what you want can also be what you need.<\/p>"}]

(dont mind the placeholder text. Cheeseburger Ipsum.)

I do have processwire in a subfolder, and my vue app is in a folder outside (just so I did not get to turned around). I also checked to make sure my api call began and ended with a slash as suggested but it doesnt seem to make a difference as of yet. My get response appears to be "200" coming from the vue app as well, so now I am just really baffled.

** Edit **

I did just find if I take my foreach statement:

<?php
$myPages = $pages->find('template=basic-page');
    $data = $myPages->explode(['title', 'summary', 'body']);
    echo wireEncodeJSON($data);
?>

and remove it outside of 

if ($config->ajax && $input->urlSegment1 == 'test-api') {

}

then the data attribute is properly filled out.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...