Leaderboard
Popular Content
Showing content with the highest reputation on 08/28/2013 in all areas
-
OH MY GOD I COULD NOT BE HAPPIER ABOUT THIS NEWS! Yes, my caps lock was on for a reason there, and yes, I'm working on a module for Jason already During my tests, Stripe can be described as nothing short of awesome. It's got the nicest looking backend (ahem) and is a doddle to use! Module on its way soon The great thing when you go to click on a button to make a payment is that stripe's module just slides down the screen in sort of a modal overlay, but the card details being entered are going straight to Stripe's site, so no PCI headaches as whilst it looks like payment details are entered on your site they're not and the customer gets a smooth experience to boot. Basically, other merchants should take note (yes, you too PayPal). EDIT: Oh, it's been around in the UK since March? Why did nobody tell me? Last time I had a look for decent UK merchants was February and didn't notice when doing the module for Jason that it was available in the UK too8 points
-
Built this Dutch site for friends of mine ( www.talk-about.nl ). It's a lightweight, straightforward website but sufficient for their needs and they are very happy with it. When it comes to computers they are a bit heavy-handed so I ended up doing the content editing myself. That experience made me change TinyMCE for CKEditor which in my opinion feels better. Installed Pro Cache and that makes the site lighting fast. First only could get it to work locally and not on the live server. Appears that Pro Cache is not working when PHP is in safe-mode. Used this as a study project and it made me very exited about ProcessWire.6 points
-
I had less hours of sleep tonight fixing one functionality that I didn't test in incognito mode while developing a website. The site went live, and this functionality was not working for other users because some pages linked by a pageField were only accessible to the superuser. For me it always worked because I was logged in while testing it. Took me a long time to find out what was happening. Advice given4 points
-
There were a few textpattern plugins released via 'ransom' - a custom fields one too if I remember correctly (hilarious!) - which went along the lines of 'I need this much money and I'll release it'. Personally if I was putting money towards module development I'd have no problem letting everyone get the benefit of it. I'm still blown away by not only the generosity of Ryan releasing ProcessWire but the dozens of module devs here that have made my life as site builder that much easier. Perhaps another approach would be to have a PayPal donate button (or similar) in the existing modules section where folk can send their cash to.4 points
-
3 points
-
Sleep?! Sleep's for wimps! Good advice though3 points
-
Dear All, I like the idea, but one thing (I think) is that Kickstarter doesn't accept projects outside the USA, while http://indiegogo.com does. Indiegogo also doesn't have the stringent project acceptance requirements that Kickstarter has, so it would be easier to start with Indiegogo. Also, IndieGogo allows a person to collect funds even if the goal is not reached, which in the case of the modules might be good. It's better to get something than nothing, and the module will still be available. I also think that the software would benefit from early release and feedback. How 'bout this? - Indiegogo Project to Create XYZ Module - Goal, $Some dollars - Perks based on dollar amounts: . $5 - listed on web page as Donor . $10 - listed on web page as Helpful Donor . $25 - listed on web page as Very Helpful Donor ... etc, etc. Indiegogo works via perks, as Kickstarter does, but with the software being free, the perks might just as well be a mention on a web page. There's no requirement otherwise. And then, as the campaign progresses, the software updates can be posted. The campaign can be fashioned with complete freedom, so the "usual method" can be easily tweaked. Campaigns can be up to 120 days. The main thing is that all of the money isn't released (I think) until the date is reached. Peter3 points
-
PW'ers be on the lookout for a Stripe module soon...just sayin'....3 points
-
Template Cache and $page->render($options) If you ever use the $page->render() to render out partials (of another page using its template file) and use template cache for the pages you're going to render and the page where you render it, it will create a cachefile. So if you go to that previously rendered and cached page, it will render that partial. If the page is accessed before a cache is created, it will cache this one and render that in as the partial, so kinda turned around. Funny effect. And many mmms and oaaahhhs To get a better understanding what's happening read on. Simple example code from a list page to render partials of articles (likely) // from the list pages template $markup = ''; foreach($products as $key => $child) { $markup .= "<dl>"; $markup .= $child->render(array('isOverview' => true, 'class' => $class)); $markup .= "</dl>"; } echo $markup; And in the template of the article // in article template file if(isset($options['isOverview']) && $options['isOverview'] == true) { // render small partial $class = $options['class']; $markup = "<dd class='$class'> <h4>$page->title</h4> <p>$page->summary</p> <a href='$page->url'>details</a> </dd>"; } else { // render complete article $markup = "<div class='product-details'> <h1>$page->title</h1> $page->body </div>"; } // output echo $markup; So now the render call $markup .= $child->render( array('isOverview' => true, 'class' => $class) ); in the list template will cache the page it renders (the small view of it). Thus if you access the page directly it will serve the cached small view of it. Ups. Solutions This is without specifying a different template file in the first argument in the render(). The effect doesn't happen when you, let's say create a new template file (ie article-small.php) and use that to render the page. Since this new template file is not connected to the template in PW it also has no cache for that render. To show what I mean is the following with the first argument the file you want the view to render. $markup .= $child->render("product-small.php", array("isOverview" => true, "class" => $class)); Still following me? Ok there's also another method to not allow a cache file to be created. There's a default options set in the render() in PW. Bingo! allowCache is what we can also use. $markup .= $child->render("product-small.php", array( "allowCache" => false, "isOverview" => true, "class" => $class )); And everything's back to normal. Just wanted to write down a little thing, as I stumbled over this recently, to scatter some keywords about this here . I think this isn't really documented somewhere but I thought it was maybe mentioned by Ryan in a thread about when he added this feature: http://processwire.com/talk/topic/3145-multiple-views-for-templates/page-2?hl=%2Brender+%2Bcaller#entry32876. Edit: Zaaakkkk and it's in Google 9 minutes !2 points
-
kickstarter There are several developers here that contribute a lot, working for fun and sharing knowledge giving us wonderful modules. But next to the respect they get, it would be nice we pay for the Cola & Pizza's they need while programming. ( Can hungry programmers code to ? ) For me as individual I won't/can't pay a decent price for good software, but with 10 members things change. Say: If an developer needs $750,- before starting the write. (I'ts only €56,-- per person, not reached, money back ) Then: Every person who paid, can download the finished module. After 3 months: The module becomes normal opensource, available for everyone. Maybe Ryan can choose some privileged developers that are capable of building quality modules. What do you think ?2 points
-
I recently created a Dribbble API wrapper module (I am pretty new at creating modules) and wanted to know if its possible to use the $image API to retrieve the external Dribbble "shot" (image), resize it and store them along with the XML in the asset cache. That way I can load an image locally via the cached file(s) for the module instead of hitting Dribbble every time for the full size images. Any thoughts on how to best do this? Here is the current state of the module on Github: https://github.com/ryanscherler/ProcessDribbble2 points
-
something like this: $im = new ImageSizer($targetPath); $im->resize($targetWidth, $targetHeight); //or $im->width($targetWidth, $options); // $options are optional!2 points
-
Something like this? $image = $page->images->first(); $img = null; if ($image->width >= $image->height) { // Lancscape $img = $image->width(900); } else { // Portrait $img = $image->height(900); } echo "<img src='{$img->url}' alt=''>";2 points
-
I'd be hesitant to say that that sort of functionality would take half an hour. That said, ProcessWire is an excellent choice for creating this sort of site as it has a very strong and easy to use API. You would be coding this yourself however, there is no plug-and-play solution. If you are happy with that idea then there are lots of examples and people on here who'd be very happy to help you out. As a flavour: <?php // Starting variables $out = "<h3>Please fill in the form below</h3>"; $error = 0; // Check if form is submitted if ($input->post->submit_form) { // Sanitize form input $name = $sanitizer->text($input->post->name); $email = $sanitizer->email($input->post->email); $phone = $sanitizer->text($input->post->phone); // Check for errors if (empty($name) || empty($email)) { $error = 1; $out = "<h3>Please provide a name and email address</h3>"; } // If no errors, process the form if ($error == 0) // Turn off output formatting before editing page values $page->of(false); // Set the new page values $page->title = $name; $page->email = $email; $page->phone = $phone; // Save the page $page->save(); $out = "<h3>Thanks for submitting the form.</h3>"; } ?> <?php echo $out; ?> <form action="./" method="post"> <label for="name">Name</label> <input type="name" name="name"> <label for="email">Email</label> <input type="email" name="email"> <label for="phone">Phone</label> <input type="text" name="phone"> <input type="submit" value="Submit" name="submit_form"> </form>2 points
-
Well now you and all the pw-members have my address - whenever in Stockholm, please abuse it - lunch, beer or whatever shall be on me for any supporters of pw! All the best, //dice2 points
-
Since you guys asked for it, I'll take a stab at a case study on the development process. Most of the development was done in about a week and a half. I started with the basic profile, but it ended up being something somewhat similar to the Blog profile in terms of how it's structured. Below I'll cover some details on the biggest parts of the project, which included data conversion, the template structure, the front-end development and anything else I can think of. Data Conversion from WordPress to ProcessWire One of the larger parts of the project was converting all of the data over from WordPress to ProcessWire. I wrote a conversion script so that we could re-import as many times as needed since new stories get added to cmscritic.com almost daily. In order to get the data out of WordPress, I queried the WordPress database directly (my local copy of it anyway) to extract what we needed from the tables wp_posts for the blog posts and pages, and then wp_terms, wp_term_relationships, and wp_term_taxonomy for the topics and tags. WordPress stores its TinyMCE text in a state that is something in between text and HTML, with the most obvious thing being that there are no <p> tags present in the wp_posts database. Rather than trying to figure out the full methodology behind that, I just included WP's wp-formatting.php file and ran the wpautop() function on the body text before inserting into ProcessWire. I know a lot of people have bad things to say about WordPress's architecture, but I must admit that the fact that I can just include a single file from WordPress's core without worrying about any other dependencies was a nice situation, at least in this case. In order to keep track of the WordPress pages imported into ProcessWire through repeat imports, I kept a "wpid" field in ProcessWire. That just held the WordPress post ID from the wp_posts table. That way, when importing, I could very easily tell if we needed to create a new page or modify an existing one. Another factor that had to be considered during import was that the site used a lot of "Hana code", which looked like [hana-code-insert name="something" /]. I solved this by making our own version of the Hanna code module, which was posted earlier this week. Here's an abbreviated look at how to import posts from WordPress to ProcessWire: $wpdb = new PDO("mysql:dbname=wp_cmscritic;host=localhost", "root", "root", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); $posts = wire('pages')->get('/posts/'); $sql = " SELECT * FROM wp_posts WHERE post_type='post' AND post_status='publish' ORDER BY post_date "; $query = $wpdb->prepare($sql); $query->execute(); while($row = $query->fetch(PDO::FETCH_ASSOC)) { $post = $posts->child("wpid=$row[ID]"); // do we already have this post? if(!$post->id) { // create a new post $post = new Page(); $post->template = 'post'; $post->parent = $posts; echo "Creating new post...\n"; } $post->of(false); $post->name = wire('sanitizer')->pageName($row['post_name']); $post->title = $row['post_title']; $post->date = $row['post_date']; $post->summary = $row['post_excerpt']; $post->wpid = $row['ID']; // assign the bodycopy after adding <p> tags // the wpautop() function is from WordPress /wp-includes/wp-formatting.php $post->body = wpautop($row['post_content']); $post->save(); echo "Saved post: $post->path\n"; } What I've left out here is the importing of images, topics, tags, and setting the correct authors for each post. If anyone is interested, I'll be happy to go more in depth on that, but didn't want to overwhelm this message with code. Template File Structure This site makes use of the $config->prependTemplateFile to automatically include the file _init.php before rendering a template file, and $config->appendTemplateFile to automatically include the file _main.php after. So the /site/config.php has this: $config->prependTemplateFile = '_init.php'; $config->appendTemplateFile = '_main.php'; You may recognize this as being the same setup from the Skyscrapers profile. The _init.php includes files containing functions we want to be available to all of our templates, and set default values for the regions we populate: /site/templates/_init.php /** * Include function and hook definition files * */ require_once("./includes/render.php"); require_once("./includes/hooks.php"); /** * Initialize variables populated by templates that get output in _main.php * */ $browserTitle = $page->get('browser_title|title'); $body = "<h1>" . $page->get('headline|title') . "</h1>" . $page->body; $side = ''; $renderMain = true; // whether to include the _main.php file The includes/render.php file that is included above includes several functions for generating markup of navigation and post summaries, or any other shared markup generation functions. Examples are renderPost(), renderNav(), renderTags(). This is similar to the blog.inc file from the Blog profile except that I'm letting these functions generate and return their own markup rather than splitting them into separate view files. I personally find this easier to maintain even if it's not as MVC. The includes/hooks.php sets up any hooks I want to be present for all of my templates. I could have also done this with an autoload module, but found this to just be a little simpler since my hooks were only needed on the front-end. The main hook of interest is one that makes all posts look like they live off the root "/" level rather than "/posts/" (where they actually live). This was in order to keep consistency with the URLs as they were in WordPress, so that the new site would have all the same URL as the old site, without the need for 301 redirects. /site/templates/includes/hooks.php /** * This hook modifies the default behavior of the Page::path function (and thereby Page::url) * * The primary purpose is to redefine blog posts to be accessed at a URL off the root level * rather than under /posts/ (where they actually live). * */ wire()->addHookBefore('Page::path', function($event) { $page = $event->object; if($page->template == 'post') { // ensure that pages with template 'post' live off the root rather than '/posts/' $event->replace = true; $event->return = "/$page->name/"; } }); Our /site/templates/_main.php contains the entire markup for the overall template used site wide, from <html> to </html>. It outputs those variables we defined in _init.php in the right places. For example, $body gets output in the <div id='bodycopy'>, $side gets output in the right <aside>, and $browserTitle gets output in the <title> tag. /site/templates/_main.php <?php if($renderMain): ?> <html> <head> <title><?=$browserTitle?></title> </head> <body> <div id='masthead'> // ... </div> <div id='content'> <div id='bodycopy'><?=$body?></div> <aside id='sidebar'><?=$side?></aside> </div> <footer> // ... </footer> </body> </html> <?php endif; ?> We use the rest of the site's template files to simply populate those $body, $side and $browserTitle variables with the contents of the page. As an example, this is an abbreviated version of the /site/templates/post.php template: /site/templates/post.php // functions from /site/templates/includes/render.php $meta = renderMeta($page); $tags = renderTags($page); $authorBox = renderAuthor($page->createdUser); $comments = renderComments($page); $body = " <article class='post post-full'> <header> <h1>$page->title</h1> $meta </header> $page->body $tags $authorBox $comments </article> "; if(count($page->related)) { $side = "<h4>Related Stories</h4>" . renderNav($page->related); } What might also be of interest is the homepage template, as it handles the other part of routing of post URLs since they are living off the root rather than in /posts/. That means the homepage is what is triggering the render of each post: /site/templates/home.php if(strlen($input->urlSegment2)) { // we only accept 1 URL segment here, so 404 if there are any more throw new Wire404Exception(); } else if(strlen($input->urlSegment1)) { // render the blog post named in urlSegment1 $name = $sanitizer->pageName($input->urlSegment1); $post = $pages->get("/posts/")->child("name=$name"); if($post->id) echo $post->render(); else throw new Wire404Exception(); // tell _main.php not to include itself after this $renderMain = false; } else { // regular homepage output $limit = 7; // number of posts to render per page $posts = $pages->find("parent=/posts/, limit=$limit, sort=-date"); $body = renderPosts($posts); } The rest of the site's template files were handled in the same way. Though most were a little simpler than this. Several were simply blank, since the default values populated in _init.php were all that some needed. Front-end development using Foundation 4 The front-end was developed with the Foundation 4 CSS framework. I started with the Foundation blog template and then tweaked the markup and css till I had something that I thought was workable. Then Mike and I sent the _main.php template file back and forth a few times, tweaking and changing it further. There was no formal design process here. It was kind of a photoshop tennis (but in markup and CSS) where we collaborated on it equally, but all under Mike's direction. After a day or two of collaboration, I think we both felt like we had something that was very good for the reader, even if it didn't originate from a design in Photoshop or some other tool like that. I think it helps a lot that Foundation provides a great starting point and lends itself well to fine tuning it the way you want it. I also felt that the mobile-first methodology worked particularly well here. Comments System using Disqus We converted the comments system over to Disqus while the site was still running WordPress. This was done for a few reasons: Disqus comments provide one of the best experiences for the user, in my opinion. They also are platform agnostic, in that we could convert the whole site from WP to PW and not have to change a thing about the comments… no data conversion or importing necessary. Lastly, ProcessWire's built-in comments system is not quite as powerful as WordPress's yet, so I wanted cmscritic.com to get an upgrade in that area rather than anything else, and Disqus is definitely an upgrade from WP's comments. In order to ensure that Disqus could recognize the relations of comment threads to posts, we again made use of that $page->wpid variable that keeps the original WordPress ID, and also relates to the ID used by the Disqus comments. This is only for posts that originated in WordPress, as new posts use a ProcessWire-specific ID.1 point
-
I promised I would share my summer-project when I got a bit further along and now most of basic design is up on the test server (still just test content though, only some of it will be there in production). Two pages remain to be styled and some minor touch-ups are left for sure, but the gist of the simple design should be visible. Clean Scandinavian has been the motto. Will update to publishable version over the coming week/weeks. I will also clean up the code and do some validation fixing etc during that time. Any suggestions, pointers and tips from you pros would be much appreciated (tough love is the ticket). Keep in mind that I am not a pro and that apart from a sole static site I helped a buddy with 10 years ago, this is my first attempt at any of this (html, design, php, cms etc), so spare me the sharpest ax. A testament to the Processwire excellence - and to all of you helpful souls on this page - is that I have been able to get at least this far with no prior experience, so I would like to extend a heartfelt thanks to Ryan, Soma, Teppo and all the rest of you that have helped form this product in general, and taken the time to help me out on specific questions. You truly rock! re le vo DOT se/en1 point
-
Hello, i missed some good futures in processwire so i decided to write my own module to do it. In Github: https://github.com/GomatoX/Language-Constants/ Installation is the same as other modules installation. Language constant module creates language_constants table in database. Purpose: This module helps to keep texts editable in cms, not hardcoded. For example, I want to have editable back button text: "back to main", so I just need to add it into language constants modulue as a constant and it would be reachable everywhere in page. How to use: Simply use $lang class and it's method display, example: $lang->display( 'constant_name' ); display( string $constant_name ) returns language constant variable. Known issues ( todo in future ): There is no available support if multilanguage is installed. No cache for constants. Needs optimization. *Still in beta conditions, posted for tests.1 point
-
ryan - just a thought, but would it be possible to make it so that fields can be shown depending on whether a user has a certain role, or even ID? Certainly roles would take you one step closer to a system I used to use where there was an editing flow with a website's content - someone would work on content, then their manager would fill out some other fields on the same page, sometimes in another tab in the editor, before finally publishing a page. It's not something that everyone needs, but to my untrained eye it also doesn't look like it would be too difficult to add (*ducks for cover*), would make it even more powerful and could be useful in many different scenarios. I guess the selector for that would be something like user.role=editor|manager as well as user.id=41 maybe for scenarios where the main admin user wants to test some stuff or have hidden fields that other superusers can't see (though that's silly as other superusers could give themselves access anyway - just thinking of odd scenarios!). Can anyone else think of uses for this?1 point
-
Hi Peter, Indeed. Something like that could be a good option too. Even some of the smallest of modules would save me more than $2.50 in time over the span of a month. - Marty1 point
-
Solved. It was a firewall issue. I can't believe how long that took to figure out. I appreciate all the help.1 point
-
While I think Asana works very well, it's better with a team effort! Since I work alone, I have found Trello to work very well for me.1 point
-
Dear Marty, I like the idea of donating to Ryan's efforts. With PayPal donations / subscriptions, it's very easy. There is also power in numbers, i.e. if a hundred people donate $2.50 a month, that's $250 per month, which is better than a sharp stick in the eye. Of course, many can donate more than $2.50 a month, but in tough economic times, it's good to give people the option of a "micro-donation", rather than the choice of "donate $50 or nothing." I have an example of this process on my website, here: http://significatojournal.com/patron At the bottom of the page, a person can choose various levels of monthly donations, or choose to make a one-time donation, as a "Renaissance Patron." I think that if Ryan set up something like that, many of us here would donate at least $2.50 a month. Peter1 point
-
1 point
-
1 point
-
1. oh, makes sense... the line starts with <? so php must be trying to parse that. I don't know how to escape it, and don't have time to look for it now, so try simply this: <?php echo '<?xml version="1.0" encoding="UTF-8" ?>'; ?> 2. you need the path of the file on the server, or the absolute url? 3. See on the default site that comes with your PW install how this is done. Open the file head.inc, and see how javascript and css files are called there. edit: thanks kongondo1 point
-
Yes, there is a hardcoded max of 999 for page numbering (defined here). Built-in pager does give you pagination links further than that, but they only work for numbers less than a thousand. You just have to take care of the rare occasions when for example a search would give more than (999 * pages_per_result_page) results. As the guys are saying in that other thread (I'm sloow today). But that's just how far the page numbering will go and has nothing to do with how many pages ProcessWire is capable of handling without any problem. We've got a site with 30000 pages and another one with 15000 pages. The bigger one is running nicely even without any kind of caching at the moment - and there is a bit more complex than just trivial search involved there. And no performance problems with the smaller one either, just to be clear =). There are even bigger PW sites around I'm sure. I think at least Antti has one in his hands and most probably others do as well. Sure one has to think a bit how to approach things to keep everything nice and fast. But it doesn't require any magic to stay on that road. Common sense and some testing along the way to see little things aren't piling up and you should be fine. In my opinion anyway. And I'm talking about the amount of pages here, not making any statement on whether to have several small sites in one install or not.1 point
-
Would you want pagination to stretch that far? Doesn't sound great for usability to have a user click <Next> hundreds of times... Or am I missing something?1 point
-
PWired...I think you misunderstand...This is not about limits to how many pages PW can handle...this is about pagination. Big difference It's right there in the post Arjen linked to...scroll down to Teppo's post...or see the code below: https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Process/ProcessPageView.module#L32 https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Process/ProcessPageView.module#L264 Btw, Wanze has built a PW site with about 100K+ pages... Edited for clarity...1 point
-
Thanks Soma, I was able to reproduce it here too. Can you try out the fix I posted to the dev branch? You'll have to undo the page move you did before, and move it back again in order to get it to rebuild its index.1 point
-
But I thought about http://www.kickstarter.com/ for processwire modules. Maybe Ryan can choose some privileged developers that are capable of building quality modules. If There's enough interest (money wise) a module can be build. I will start a new Topic !1 point
-
Probably not a lot at this point! But very soon Any ideas on what would be next in line? I guess it has to be something Ryan wants to do too!1 point
-
I've recently started using https://asana.com/ Works great.1 point
-
Hi and welcome to PW. Simply set up a new permission called: page-publish and make sure that is checked for the admin user's role and unchecked for the others.1 point
-
Hello folks! I've been playing with ProcessWire a lot recently, and have just launched site number 3 - Bishop Auckland Table Tennis Club. Some of my family members are associated with or are members of the club, so this was a bit of a favour for them. I haven't used many "additional" modules - just CropImage and MapMarker.1 point
-
@Hani, I used this module in 2 of my lasts projects I I must say I love it. TNX for creating!1 point
-
1 point
-
I built the site with PW just for my convenience. The client does not want to make any major changes frequently, so the content is more or less static. The output and upload is scripted on my end, so it's just a matter of a single command line command =)1 point
-
It might seem like treachery to mention this one but it got me over the line when I needed to get some documentation done quickly: http://www.daux.io/1 point
-
Ryan, glad to see you working on this module! It looks like you already figured this out, but /site/assets/cache/[your dir] is usually a good place to store things like XML cache files. If connected with a page, then just use the page's files dir ($page->filesManager->path or $page->[your files field]->path). Horst is right that you can add files to pages and manipulate them using PW's methods from there. He's also written an excellent manipulation module. If you just need to resize images, also look into PW's ImageSizer class, which is ready to operate on any file (doesn't need to be connected to a page). In the dev branch, I'm about to push some updates to that class from Horst that add sharpening and auto rotation among other tweaks. Lastly, I wanted to mention that the dev branch also has the WireHttp class, which you may find more convenient than CURL.1 point
-
1) you may do this by using a hidden tools page with an images field and than you only have to use $page->images->add($shotImageUrl) to save the image to the tools page assets directory. And you have it as PageImage and you can do all image api stuff 2) I have uploaded a new module for Image Manipulation. With this you are able to use some well known image methods (width, height, size) and you can store the image together with your xml or json file instead of creating and using a tools page with InputFieldtypeImage. Example (this could be somewhere in your makeRequest method): // get your image from dribble and save it to your cache directory $shotImageUrl = 'http://dribble.com/some/path/to/image.jpg'; $imgCacheFile = $this->cachePath . md5($url) . '.image.jpg'; $result = file_put_contents($imgCacheFile, file_get_contents($shotImageUrl)); // if $result is not false and greater than zero the image was successfully saved, // now you can load the $imgCacheFile into the ImageManipulator, resize it and save it by overwriting the $imgCacheFile $boolResult = wire('modules')->get('PageImageManipulator')->imLoad($imgCacheFile)->resize(360)->save(); // thats all PS: if you want rely on the PageImageManipulator module, you can set it as needed dependency for your module: public static function getModuleInfo() { return array( // ... 'requires' => array('PageImageManipulator'), ); } see: http://processwire.com/talk/topic/778-module-dependencies/1 point
-
I'll cover these each separately. First I'll start with the images, and will come back to the others a little later when I've got more time. WordPress really only uses images for placement in body copy, so I extracted the links to them right out of there and imported them that way. I did this after the pages had already been imported. In order to keep track of which images had already been imported (so that I could feasibly run the importer multiple times without getting duplicate images), I turned on ProcessWire image "tags" option, and stored the original filename in there. Here's the function I used, which I've used many different variations of over the years with different sites. You basically just give it a $page you've already imported (but is still linking to the old site's images) and it converts the images linked in the body copy from the old site to the new. function importImages(Page $page) { if(!$page->id) return 'You need to save this page first'; $out = ''; $body = $page->body; // find all images reference in the 'body' field $regex = '{ src="(http://www.cmscritic.com/wp-content/uploads/[^"]+)"}'; if(!preg_match_all($regex, $body, $matches)) return $out; foreach($matches[0] as $key => $fullMatch) { $url = $matches[1][$key]; // image URL $tag = basename($url); // image filename $tag = wire('sanitizer')->name($tag); // sanitized filename $image = $page->images->getTag($tag); // do we already have it? if(!$image) { // we don't already have this image, import it try { $page->images->add($url); } catch(Exception $e) { $out .= "<div>ERROR importing: $url</div>"; continue; } $numAdded++; $image = $page->images->last(); // get image that was just added $status = "NEW"; } else { $status = "Existing"; } $image->tags = $tag; // replace old image URL with new image URL $body = str_replace($url, $image->url, $body); // report what we did $out .= "<div>$status: $image->basename</div>"; } // assign the updated $body back to the page $page->body = $body; // return a printable report of what was done return $out; }1 point
-
I agree, I think export/import methods like this on Fields and templates would be nice. There's a lot of considerations though, especially on import. Like whether individual fields already exist or not, whether those field definitions reference external things (like page IDs). That's not to say it isn't doable, but just that there is potential for it to get quite a bit more complex than it first appears. But I would like to implement some API level expor/import functions for this soon, to at least get things moving forward. I've already been working on similar export/import functions for Page objects (which you see in the latest dev branch, though they aren't yet active).1 point
-
When you get into sending POST data, ProcessWire has an http class that you can use rather than something like CURL. The benefit of using PW's WireHttp class is that it will fallback to sockets if it has to, ensuring the class works just about everywhere. Here's an example of the same web service we outlined above, except that this one posts to it: $data = array( 'username' => 'ryan', 'pass' => 'mypass', 'email' => 'info@grab.pw' ); $http = new WireHttp(); $result = $http->post('http://www.domain.com/path/to/service/', $data); if($result) { $result = json_decode($result, true); if($result['status'] == 'success') echo "Success! $result[message]"; else echo "Error! $result[message]"; } else { echo "error posting data"; } As a side note, this service is using the same password for the user to add, and the web service password. In reality, you'd probably want those to be different things.1 point
-
The PW API is always the same regardless of context. One of strengths of PW is in it's flexibility when it comes to sending or receiving web service data, and this is one of the things I use it for quite a lot. But you do have to tell it what to do, rather than it telling you what to do. At the simplest level, you could validate against an IP and/or password for authenticating the request. That may or may not be adequate, depending on who/what you are dealing with. In either case, use POST rather than GET. Here is a simple web service that adds a new user (written in the browser / not tested). This would simply be code written into a template file. Ideally you'd split this up a bit more, but just trying to keep it self contained for example purposes. $message = ''; $success = false; if($input->post->pass === 'mypass' && $_SERVER['REMOTE_ADDR'] === '123.123.123.123') { $name = $sanitizer->pageName($inpust->post->username); $pass = $input->post->pass; $email = $sanitizer->email($input->post->email); if($name && $pass && $email) { $u = $users->add($name); if($u->id) { $u->pass = $pass; $u->email = $email; $u->addRole($roles->get('some-role')); $u->save(); $success = true; $message = "Added new user: $u->name"; } else { $message = "username '$name' is already taken"; } } else { $message = "missing required fields"; } } else { $message = "you aren't authenticated"; } $result = array( 'status' => ($success ? "success" : "error"), 'message' => $message ); echo json_encode($result);1 point
-
Sorry I didn't read high up enough on the page before and missed this: I understand what you are saying here and these are good points. But I want to clarify that the file is a component of a template. They are part of the same thing. It's like a car and it's engine. When we are on the file system, it's assumed we are dealing with files. If we open the hood on the car it's assumed we're going to find an engine… yet we're still talking about a car. When you are working with template files, you are working with the template's representation on the file system. There is no other representation of a template on the file system. Given that, I don't think it matters whether we call it ./templates/, /files-for-templates/ or ./template-files/, so I'll choose whatever is easiest to type. In that URL on processwire.com, I think it's more just a matter of trying to make URLs are short as possible. Template-files would technically be a more accurate fit in that URL. Though everything you do with the API takes place in files, and /api/templates/ at least provides context to the term. But I agree that template-files would have been a better URL name here. But I'm also not sure it matters enough to change it (already been there for a long time).1 point
-
Different CMSs use different terminology. My opinion is that I'm not comfortable letting another CMS define our terminology. I think we have to stick with the actual definitions of terms. So here is the dictionary: I can't think of any term that better describes what Templates are in ProcessWire: Oops, not that one, sorry This one: ...and... This is what Templates are in PW. A template in PW also has these components: - fields - file - access - urls - cache One large component of a template in PW is it's file. I think the term for that naturally should be: "template file". It could also be "output file", but a template file doesn't necessarily have to produce output so I don't want to use a term with any built-in limitations. Of course, the term "template file" also fits with the definitions above when qualified with "file". A template file also has a natural dependency of the fields used by the page (template) it is processing. The two are interconnected and part of the same thing. I think that changing the terminology or splitting these things up is unnecessary complexity. Some people may want to split them on occasion for technical reasons (and PW will let you in advanced mode), but I want to always target simplicity first. My opinion is that terminology like "template and "template file" fit the definitions and relate to each other in the appropriate manner. But I'll also qualify that by saying that it's also what I'm used to, and I think we all naturally prefer what we're used to.1 point