Change Wordpress REST response - wordpress

I have a plugin that puts custom post types onto a map. It uses Leaflet and specifies a REST API link as the source of its data. A map is displayed with a number of location markers and when clicked a details box pops up with the name of what's at that location and there's a hyperlink in this details box which when clicked takes the user to another page on the site. Here's what is specified as the data-endpoint source:
http://rd-dev.local/wp-json/citadela-directory/map-data/points/citadela-item?dataType=markers&category=&location=&only_featured=0
This call returns JSON that looks like this:
{"total":40,"points":[{"track":[],"coordinates":{"longitude":14.726660728455,"latitude":46.813816070557003},"title":"Name of place","permalink":"http:\/\/rd-dev.local\/item\/something\/","address":"Address, line 2, Someplace, Some Country","image":"http:\/\/rd-dev.local\/wp-content\/uploads\/2020\/12\/0b-1-150x150.jpeg","postType":"citadela-item","faIcon":"fas fa-circle","color":"#0085ba"}, ... etc
Part of each record in the response is a link to a url on the site, which the user clicks to see the detail:
http:\/\/rd-dev.local\/item\/something
I want to change the page that users see when they click a location so it occurred to me that one way, and which at my level of knowledge is probably the simplest, is to alter the JSON response that Wordpress gives. Specifically, i want to change all occurrences of "item" to a something different.
Is there a way to change the JSON stream as it is sent out by the REST API?

I solved this. I searched for register_rest_route occurrences in the source files and was able to find one for this particular route. The register_rest_route call includes a callback function where the response is constructed. It was then a case of putting that response through text replacement calls.

Related

Purpose of tilde delimited values in URL fragment instead of GET params

I came across an unusual URL structure on a site. It looked like this:
https://www.agilealliance.org/glossary/xp/#q=~(infinite~false~filters~(postType~(~'post~'aa_book~'aa_event_session~'aa_experience_report)~tags~(~'xp))~searchTerm~'~sort~false~sortDirection~'asc~page~1)
It seems the category, pagination and sort options of a widget on the page injects and reads through these values. Does this format for storing data in the URL have a name, or is this an esoteric format someone made?
What's the purpose of doing this over using regular GET params, or at least using a more conventional format after the fragment?
If you inspect the URL carefully, you'll see that the parameters you describe are placed after the fragment (#), meaning they're not sent to the server but used by the client instead.
In this case, the client (JavaScript) builds them into something like an ElasticSearch query that's then POSTed to the server, in order to update listing you see on your screen.

Extract part of an URL behind a login page with Paw

I'm a newbie but I think Paw can do what i need :
I need to extract a session id behind a login page.
I go to https://admin.booking.com, filling the form (login and pass) and the landing page behind includes a session id :
https://admin.booking.com/pc/index.html?ses=xxxxyyyyyzzzzz11112222233333
I'd like to :
1) Push credentials with Paw as part of my request,
2) get the above item (ses) item as a response so i can use the php script extension provided by Paw and then call this script "on demand".
Is this possible ? If so, what should i do ?
Thanks for your help
UPDATE*: we've added a documentation article to describe the process a little more: Login via a web form in Paw. We've detailed the process to deal with CSRF tokens too.
Paw isn't quite yet ready for handling web/HTML forms. Though, there's one way to do it the right way: if you inspect the form with the Chrome dev tools you'll find the name of the input from the DOM/HTML:
In your case, you have the inputs: loginname, password, lang.
Also, find the <form…> tag to see what's the action attribute. If there's no action attribute (like in your example), it means the target URL for your form is the current page's URL (https://admin.booking.com/ in your case). Also, make sure the method="POST" is also there in the <form…> tag, otherwise this method won't work.
Then jump into Paw and set:
URL (in your case https://admin.booking.com/)
method to POST
go to the Body tab and use "Form URL-Encoded + fill up the fields from your form
If all works, you'll see Paw show a redirection request, and if you go to the right-hand side panel under "Response" > "Headers", you should see a Location header with a value similar to the URL you initially mentioned (https://admin.booking.com/pc/index.html?ses=xxxxyyyyyzzzzz11112222233333). Hurray! You got your value into Paw!
Now that you have that, you can create in a new request (click on the + button at the bottom of the left-hand side list). And wherever you want to use this session token/ID, you can insert a dynamic value to retrieve that URL value. You have more infos here, in our docs, but I'll describe the steps here:
On whichever field you want to insert the token, right-click and pick Responses > Response Header.
Make sure you pick the first request in the "Request" dropdown menu, and enter Location in the "Header" field:
You should see the value of the Location header of the previous response appear here.
Now what you want to do is to extract only the part you want (i.e. the value of the ses param in your case). For that you'll need that extension for Paw, so please install it now: https://luckymarmot.com/paw/extensions/RegExMatch
Copy the dynamic value you have just inserted (the blue token), and right-click on that field to insert a new dynamic value, and pick Extensions > RegExp match:
In the Input field, paste the previous dynamic value you copied. And use the RegExp field to write a regular expression that will successfully extract the part of the URL you want (this should work in your case ses=(.*)).
Now that you're set up. You should be able to use this little new blue token wherever you like and automagically extract the value from the previous form. And whenever you send again the initial request, and get a new token, everything else will also update! :)
It was a little long guide, but I hope this will help you and hopefully others too.

Is it possible to return HTTP code 200, but give a "better" url without using 3xx?

Consider StackOverflow, where each question has a unique ID, but URLs are often overridden to include a stub in the URL. For readability and other reasons the stub helps users know they are at the right place.
I have a site that returns 200 when calling a URL like:
http://stackoverflow.com/questions/28057406/
But want the URL to update to:
http://stackoverflow.com/questions/28057406/is-it-possible-to-return-http-code-200-but-give-a-better-url-without-using-3x
The first call is technically valid and the code can retrieve the object and render it perfectly fine, but I'd like to update the URL to use the stubified one.
I'd prefer to do this without a redirect as just getting the ID causes a database call to get the object. Which would mean with a redirect the process would be:
Call http://stackoverflow.com/questions/28057406/
Retrieve item 25257999 from the database to get the name to make the stub
Redirect to http://stackoverflow.com/questions/28057406/is-it-possible-to-return-http-code-200-but-give-a-better-url-without-using-3x
New HTTP Call, so retrieve item 25257999 from the database to render the final page.
If possible I'd like to not use Javascript either.
So, is it possible to return Location as part of a HTTP header with a status code of 200 and the actual page, or am I stuck using 3xx calls or Javascript?
If you are just doing HTTP, you can either choose to redirect, or not choose to redirect... You can also (with Content-Location) tell the client that the canonical address is actually somewhere else... but no browser will respond to that.
To avoid the database-call, you could of course just cache the result.
If you are in a browser however, you can dynamically update the current address without forcing a refresh, with window.history.pushState.
For more information about that call, see this other SO answer:
Modify the URL without reloading the page

Link formation in a third-party .aspx website

I want to understand what link is formed when I click print button on http://recruitment.cdacmohali.in/TETPB/Regprintagain.aspx
Sample data is 2011360220 and 25/05/1980
I want to integrate it with my website and get the url it it making so that in the url I can pass the registration number and dob as variable and see the complete results.
I think it is using Session. You can not pass the data by QueryString

How to apply the PUT verb in a REST request?

I'm working on a REST server. I have an order RESOURCE.
From my understanding the PUT verb should create a new order based on the URL. My question is: How can this work if the resource is new and you don't know the ID of the new order?
I know the debate about POST vs PUT, but I'm quoting the w3 specs for PUT http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
"If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI"
In RESTful APIs, PUT is typically used to update a resource or create one if it doesn't exist at the specified URL (i.e. the client provides the id). If the server generates the id, RESTful APIs typically use a POST to create new resources. In the latter scenario, the generated id/url is usually returned or specified in a redirect.
Example: POST /orders/
According to W3C Both PUT and POST can be used for update and/or create.
The basic difference between them is how the server handles the Request-URI. PUT URI identifies the entity and the server should't try to map it to another URL, while POST URI can be a handler for that content. Examples:
It's OK to POST a new order to /order, but not a PUT. You can update order 1 with a PUT or POST to /order/1.
To put it simply POST is for creating and PUT is for updating. If you don't have an ID for an object because it isn't created yet, you should be using a POST. If an object DOES exist and you just don't have the ID for it, you're going to have to search for it using a GET of some kind.
The thing to remember is Idempotence. A PUT (and GET for that matter) is idempotent. Basically meaning, you can hit the same URL over and over and it shouldn't make a difference the 2nd or 3rd time (It edits the data once, and calling it again it doesn't make that change again). However a POST is not idempotent. Meaning, you hit the same URL 3 or 4 times in a row and it's going to keep changing data (creating more and more objects). This is why a browser will warn you if you click back to a POST url.
You say, "don't know the ID of the new order" therefore the following is not true "URI is capable of being defined as a new resource by the requesting user agent", therefore PUT is not appropriate in your scenario.
Where is the confusion? I am of course assuming the Id would be part of the URL.

Resources