Jump to content

Creating pages using API


Arkster
 Share

Recommended Posts

Hello,

I'm wondering if there is a way to create a page using the API. I'm looking to create a photography type site that would house a lot of images, so I wanted to create a new page for each image. The way I was thinking I would do that is to code a page that would reside in the admin area with some kind of upload script integrated (eg. http://www.uploadify.com/) then to create a new page for each image uploaded and assign that image to images field, and then assign the EXIF data to fields of each of the newly created images. I also was thinking there could be a field called "tags" that when uploading could be filled out and assigned to the pages.

Is it possible/recommended to create pages like this, or might someone have a better idea on how to create this type of site?

Also, since I'd like all the images to exist in high-res, will it be possible to make the re-sized versions have a more cryptic filename (eg. "random_string.123x123.jpg" instead of "actual_filename.123x123.jpg") so people could not easily download the full resolution version, or would that be a lot of custom coding?

Thank you,

Austin

Link to comment
Share on other sites

I'm wondering if there is a way to create a page using the API.

http://processwire.com/api/variables/pages/

<?php
// Creates pages, saves, adds image and saves again
$skyscraper = new Page();
$skyscraper->template = $templates->get("skyscraper"); 
$skyscraper->parent = $pages->get("/cities/atlanta/"); 
$skyscraper->title = "W-Hotel Tower"; 
$skyscraper->body = "This is a nice hotel and it has a helicopter landing pad on top of it."
$skyscraper->save(); 
$skyscraper->images->add("http://starwoodhotels.com/w-atlanta.jpg"); 
$skyscraper->save();

Is it possible/recommended to create pages like this, or might someone have a better idea on how to create this type of site?

Yes, it is possible - though there is little bit of coding work ahead. You could take a look of my redirects module on how to create admin pages using Process class: https://github.com/apeisa/ProcessRedirects

Other option would be to create this on template level, outside of admin (of course using authentication still). But probably creating this inside admin is better option.

Also, since I'd like all the images to exist in high-res, will it be possible to make the re-sized versions have a more cryptic filename (eg. "random_string.123x123.jpg" instead of "actual_filename.123x123.jpg") so people could not easily download the full resolution version, or would that be a lot of custom coding?

This is pretty simple. I would create two image fields: image_highres and image_preview. When creating image_preview I would use current filename and resize it to maybe 1024 width. After that I would rename the original image to something unique (maybe md5 hash from pageID, or maybe just pageid?) and save that image to image_highres. That way you would have both images available as pw fields, but when using image_preview in your templates no-one could guess the filename of image_highres.

Hope this helps you even a little bit - I'm happy to help you with this if you need more support.

Link to comment
Share on other sites

Austin,

Apeisa has great suggestions. I also wanted to inquire about why you'd store 1 image per page rather than multiple images? Is it mainly because of the EXIF fields? If so, I wanted to mention that PHP has some built-in EXIF functions that may help:

http://www.php.net/manual/en/ref.exif.php

For tags, you could  use the built in description field included with each image. PW also lets you upload a ZIP file full of images, and it'll extract them all for you and bundle them into the field -- this can be a real time saver.

There's certainly nothing wrong with using 1 page per image, and it may be the right approach, but I just wanted to make sure I understood. There may be a way you can accomplish what you need without having to do the multi-page and custom module approach.

As for preventing access to the full size image, you could also use an apache rule to block all images where PW has them stored, EXCEPT for those that have the resize dimensions in the filename. This would accomplish what you are asking for and it would be bulletproof, directly blocking access rather than having to hide the filename. To do this, place the following snippet somewhere in your /.htaccess file after the line that says "RewriteEngine On":

# Block access to all images in /site/assets/files/[0-9]+/ that don't have 
# dimensions specified in the filename
#
RewriteCond %{REQUEST_URI} (^|/)site/assets/files/[0-9]*/.*\.(gif|png|jpg|jpeg)$ [NC]
RewriteCond %{REQUEST_URI} !.*[1-9][0-9]*x[1-9][0-9]*\..*
RewriteRule ^(.*)$ - [F]

Note that this will block ALL non-resized images in your site. It won't block them from PW, which reads and resizes them from the file system, but it will block all http requests to them. So if there is a place in your site where you don't want this behavior, you would still have to create a resized version in your template code in order for the image to be http accessible. You could do this just by creating a version that's the same size, or slightly smaller than the original.

Link to comment
Share on other sites

Thanks Apeisa and Ryan for your help! I looked and looked but somehow I missed that obvious bit in the docs.

Apeisa, that sounds like a good solution for keeping visitors viewing the low-res versions of the pics. Only thing is that would require me to save-out two versions...not a big deal, but Ryan I think what you propose would work really well here. Actually, I guess I could make PHP do all the work going the two images per page approach too. I mainly want the high-res versions as a backup. I'll have to give it some more thought.

Ryan I want to a create a separate page for each photograph because it seems like it would give me the most flexibility - this way I could build out the front-end to behave exactly as if it was one page need be, in addition to allowing someone to view details and a image description, maybe related images as well. Plus I want to get away from the whole lightbox craze (not that there is anything wrong with lightboxing images - it is quite elegant), and I want to give more importance to each image, allow bookmarking, etc. So it comes down to flexibility. But it sounds like PW is pretty flexible in this regard itself, it's good to know about the zip file unpacking abilities of PW.

I'm a novice when it comes to this, so how would I go about creating a custom page in the backend? If I go to create a new page under "Admin", what is the "process" field and how would I add my own? I know I could just create a new template but it would be nice if it linked to/from and matched the rest of the backend. Would I go about this by building a module?

Something that comes to mind is creating a normal page with it's own template that I can upload images to, give descriptions, etc.. Then just visit that page once, and have PHP in that template create new pages from it's own images and then delete them from itself. Next time around same thing. It would always be an empty page really. I could make the permissions such that only the admin when logged in could access this special page. What do you guys think about that solution? There is probably a much better way to do this.

Link to comment
Share on other sites

Creating a new Process module would be the way to go if you want to create something that's easily reusable. But if this is a one time need, then you may find it quicker to do the other thing you describe... if I understood correctly, that is: create a page where you upload a bunch of images to (perhaps in a ZIP file) and it creates all the individual image pages for you when you view it. I think this seems like a reasonably simple approach because you could just build the functionality in a template file. Something like this (written in the browser, so may not be 100%):

<?php

$numImages = count($page->images); // images is a field on this page that can have multiple images

if($numImages && $input->get->go) { 

   // there are images and the user has indicated they want to create the pages
   // determine where you want the pages created, for example: 
   $parent = $pages->get("/image-gallery/");

   // image-item is a template where you have a single image field called 'image'
   $template = $templates->get("image-item");

   // iterate through the current page's images, and create one new page for each of them
   foreach($page->images as $name => $image) {

       $p = new Page();

       $p->template = $template;
       $p->parent = $parent; 
       $p->name = $name; 
       $p->image = $image->filename;

       if($image->description) $p->title = $image->description;
           else $p->title = $name; 

       $p->save();       
       echo "<p>Created: {$p->url}</p>";
   } 

   // once images are processed, remove them
   $page->images->deleteAll();
   $page->save();

} else if($numImages) {

   // there are images -- check if the user wants to create pages
   echo "<h2>Found $numImages images</h2>";
   echo "<p><a href='{$page->url}?go=1'>Click here to create pages for them</a></p>";

} else {

   // there are no images here, so render the gallery page instead    
   echo $pages->get('/image-gallery/')->render();

}
Link to comment
Share on other sites

Nice approach. Ryan's example could be extended so that after first run template could be changed for something else, like image-category. Then it wouldn't try to create image pages again, but show them instead.

Also maybe get var or something that is required before template tries to create pages could be nice.

Link to comment
Share on other sites

Updated the original example for @apeisa's suggestions.

Also note it deletes all the photos from the current page after it's created all the other pages, so there isn't any risk of those pages being created more than once.

Link to comment
Share on other sites

Yes, that is exactly what I was thinking, only better.

Thank you! I think I'll go the easy way for now, and in my free time fool around with creating a module - I could see myself wanting to do this in the future, and I think having a gallery solution for PW would be great. Apeisa, I'm looking through your ProcessRedirects module trying to get an idea of how I might go about this, but I think I'll need to stare at it for a while more before it starts making sense to me.

Link to comment
Share on other sites

Arkster: the on-site documentation for modules is minimal at present, but the code-documentation is pretty good (in the actual module files). I will be putting together strong documentation/guide for module development with 2.1/2.2 but these are good files to look at:

https://github.com/ryancramerdesign/P21/blob/master/wire/core/Module.php

https://github.com/ryancramerdesign/P21/blob/master/wire/core/Process.php

Those files outline every detail (especially Module.php). Your module doesn't even have to extend one of PW's classes if you don't want it to. The only thing it has to do is provide two functions: getModuleInfo() and init(). The rest are optional -- you'll see examples of them in Module.php, but they are all commented out since they are optional. As a result, that Module.php file is primarily documentation.

The Process.php is just a type of module -- I included it above since you mentioned this may be the type of module you want to create. If you create this type of module, you do have to extend the Process class (unlike a regular module where you don't necessary have to extend anything). 

Also, any time you want to build a module, just post as many details about what you are trying to do in the Modules board, and I'll be happy to get the skeleton started for you to build from too. If you need to hook into something, I can tell you what to do (or if a hook doesn't yet exist, I can add it in the core).

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...