How do you handle multiple files in a form submission using Apache2::Upload? - perl

I'm writing a small web application using Perl, HTML::Mason and Apache.
I've been using Mason's usual <%args> method for receiving 'normal' form parameters, and Apache2::Upload for receiving files.
However, I want to write a page that allows a user to upload multiple files, and I'd like to take advantage of HTML5's multiple attribute to input fields. This will look to the server as though there were multiple file inputs in the form with the same name.
The interface for Apache2::Upload doesn't seem to directly support this, allowing you instead to just get the data for a file with a particular parameter name. The documentation alludes to using APR::Request::Param::Table, but I can't find any documentation for doing that.
Please note that I'm not interested in answers that involve adding extra file input fields with different names. This is trivial to handle on the server, and my question doesn't involve front-end scripting at all.

Use the multiple attribute (in the form as you described) and then, after submission, call the Apache request object's upload method. That will give you a list of Apache2::Upload instances.
Good luck!

Related

WEB: Submitting files + text fields, use single form or separate?

I'm currently working on a simple frontend that will allow users to input data into text fields and also upload files on the same form.
I know that I'll have to use multipart/form-data in order to send the files, but I'm curious as to what would be the best way to also send the text data. My options are:
Submit files and text data in a single form using multipart/form-data
Separate files and text data between two different endpoints, allowing me to format the text data to JSON client-side before sending it off
I don't think doing either would be terribly difficult, but I'm curious as to what is generally considered to be the best practice in this scenario.
This depends on the workflow you expect of your users.
If the fields you want them to fill in are tightly bound to the file you upload, do them all in one form. For example, if it's an image being uploaded and the field contains the image's caption, they go together and should be in a single form.
If it makes sense from your page to just upload the file, or just fill out the fields in the form and submit them, use two form objects.
You probably won't know how well this works until you do some usability testing. You may have to change it up to get everything working smoothly.

In general, would it be redundant to have two GET routes for users (one for ID and one for username)?

I'm building a CRUD for users in my rest API, and currently my GET route looks like this:
get("/api/users/:id")
But this just occured to me: what if a users tries to search for other users via their username?
So I thought about implementing another route, like so:
get("api/users/username/:id")
But this just looks a bit reduntant to me. Even more so if ever my app should allow searching for actual names as well. Would I then need 3 routes?
So in this wonderful community, are there any experienced web developers that could tell me how they would handle having to search for a user via their username?
Obs: if you need more details, just comment about it and I'll promptly update my question 🙃
how they would handle having to search for a user via their username?
How would you support this on a web site?
You would probably have a form; that form would have an input control that would allow the user to provide a user name. When the user submit the form, the browser would copy the form input controls into an application/x-www-form-urlencoded document (as described by the HTTP standard), then substitute that document as the query_part of the form action, and submit the query.
So the resulting request would perhaps look like
GET /api/users?username=GuiMendel HTTP/x.y
You could, of course, have as many different forms as you like, with different combinations of input controls. Some of those forms might share actions, but not necessarily.
so I could just have my controller for GET "/api/users" redirect to an action based on the inputs?
REST doesn't care about "controllers" -- that's an implementation detail; the whole point is that the client doesn't need to know how the server produces a representation of the resource, we just need to know how to ask for it (via the "uniform interface").
Your routing framework might care a great deal, but again that's just another implementation detail hiding behind the facade.
for example, there were no inputs, it would return all users (index), but with the input you suggested, it would filter out only users whose usernames matched the input? Did I get it right?
Yup, that's fine.
From the point of view of a REST client
/api/users
/api/users?username=GuiMendel
These identify different resources; the two resources don't have to have any meaningful relationship with each other at all. The machines don't care (human beings do care, so we normally design our identifiers in such a way that at least some human beings have an easy time of it -- for example, we might optimize our identifiers to make things easy when operators are reading the access logs).

Change CKAN API Interface - are there limitations on the API?

I've looked around the site to see if there are any people who have changed the CKAN API interface so that instead of uploading documents and databases, they can directly type onto the site, but I haven't found any use cases.
Currently, we have a page where people upload data sets through excel forms that they've filled out, but we want to make it a bit more user friendly by changing the API so that they can fill out a form on the page rather than downloading the template, filling it out and then uploading it.
Does CKAN have the ability to support this? If so, are there any examples or use cases of websites that have use forms rather than uploads?
This is certainly possible.
I'm not aware of any existing extensions that provide that functionality, but you can check the official list of CKAN extensions if there's anything that fulfills your needs.
If there is no existing extension that suits you then you could write your own, see the extension guide for details on how to do that.
Adding an API function to CKAN's API is possible, but probably not what you want in this case: the web UI usually does not interact with CKAN via the API but via Flask/Pylons controllers. Hence, you would add your add controller which first serves your form and then processes the submitted inputs.
You can take a look at the ckanext-pages extension, which does exactly that (for editing static pages instead of datasets, but your code would be similar).

Yesod forms with page flow

Certain forms are too complicated to have them fit on one page. If, for example, a form involves large amounts of structured data, such as picking locations on a map, scheduling events in a calendar widget, or having certain parts of a form change depending on earlier input, it is of value to be able to break up a certain form over multiple pages.
This is easy to do with dynamic web pages and Javascript, as one would simply create a tab widget with different pages, and the actual submitted form would contain the whole tab widget and all of its input fields, yielding a single POST request for the entire operation.
Sometimes, however, it takes a long time to generate certain input fields; they might even be computationally intensive even after the page has been generated, taxing the low-end computer user's browser. Additionally, it becomes difficult or impossible to create forms that adapt themselves based on earlier input.
It therefore becomes necessary to split up a certain form over multiple full page requests.
This can prove to be difficult, especially since the first page of a form will POST to /location/a, which will issue a redirect to /location/b and requested as GET by the client. Passing the stored form data from POST /location/a to GET /location/b is where the difficulty lies.
Erwin Vervaet, the creator of Spring Web Flow (A subproject of the Spring framework, mostly known for its dependency injection capabilities) once wrote a blog article demonstrating this functionality in said framework, and also comparing it to the Lift Web Framework which implemented similar functionality. He then presents a challenge to other web frameworks, which is further described in a later article.
How would Yesod face this problem, especially considering its stateless REST-based nature?
Firstly, there's no pre-built solution to this in existence yet (that I'm aware of at least). And I'm not familiar with how the other frameworks mentioned solve the problem. So what I say here is pretty much conjecture. I'm fairly certain it would work, however.
The crux of the issue here is encoding page A's POST parameters into the GET request for page B. The simplest way to do that would be to stick page A's POST parameters into a session variable. However, doing so would break navigation pretty thoroughly: back/forward wouldn't work at all as described.
So we come back to REST: we need to encode the POST parameters into the request itself. That really means putting the information in either the requested path, or the query string. And the query string probably makes the most sense.
I'd be concerned about putting the raw POST parameters into the query string, as that would allow any proxy server to easily snoop the contents. So I'd like to leverage the existing cryptography from clientsession. In other words, we'll stick a signed, encrypted version of the previous form submission in a query string parameter.
To make it a bit more concrete:
User goes to page A via GET.
User submits page A via POST.
Server validates form submission, gets a value, serializes it, encrypts/hashes it.
User is redirected to page B as a GET, with a query string parameter containing the encrypted/hashed value from page A.
Continue this process as many times as desired.
On the final page, you can decrypt the query string parameter and have all of the form submissions.
This looks like it would be a fun add-on package to write if anyone's interested.

How to implement Wordpress-like Permalink

I was thinking about a building a CMS, and I want to implement the wordpress-like permalink for my posts. How do I do that?
I mean, How do I define the custom url structure for my pages?
What language are you using? I'm assuming that you are thinking about PHP (given your reference to word press). You have a few options:
Mod-Rewrite
Router
In my opinion, the best option is to find a modern web framework that provides good routing functionality. Furthermore, look at modifying an existing CMS (many exist; you seem to have heard of word press).
I'd recommend creating links that pass in a URL parameter such as ..."http://...PostID?123&CatID=232&..." so that when the person clicks on that particular link, you can parse the parameters in the URL, and get the exact post based on id, or even do further filtering by passing in other fields as needed.
If you want to build the whole thing yourself, first understand what a front controller is, as it really addresses the underlying issue of how do you execute the same code for different URLs. With this understanding, there are two ways to attack the problem with this design pattern: URL rewriting or physical file generation.
URL Rewriting
With URL rewriting, you would need intercept the requested URL and send it onto your front controller. Typically this is accomplished at the web server level, although some application servers also act as web servers. With Apache, as others have posted, you would use mod_rewrite with a rule that looks something like this:
RewriteRule ^/(.*) /path/to/front/controller.ext [E=REQUEST_URI:%{REQUEST_URI},QSA,PT,NS]
With this rule, the path originally requested with be sent to the front controller as a variable called "REQUEST_URI". Note, I'm not sure the right syntax in PHP to access it. In the front controller hash (e.g. MD5) this value and use it to lookup the record from a database - take into account whatever hashing algorithm you use will produce duplicates. The hash is necessary if you allow URLs over whatever the max column size is in your database for varchar data, assuming you can't search on CLOBs.
Physical File Generation
Physical file generation would create a file that maps to the permanent URL you're imagining. So you'd write something that creates/renames the file at time it's posted. This removes the need for storing a hash and instead you place information about the post you want to serve inside that file (i.e. ID of the post) and pass that along to the front controller.
Recommendation
My preference is the URL rewriting approach, so you don't have to worry about writing dynamic code files out at runtime. That said, if you want something with less magic, or you're expecting a lot of requests, the physical file generation is the way to go because it's more obvious and requires the server to do less work.