-
Posts
16,772 -
Joined
-
Last visited
-
Days Won
1,531
Everything posted by ryan
-
Shane, glad that did the trick! Thank you for your inquiry about donations, that's very nice of you. We don't have anything like that at present, but maybe will set it up someday. I certainly don't expect people to donate anything. But if they are wanting to, time donations are always appreciated. Time can mean anything, whether blogging about PW, sending the occasional tweet, helping out others on the forum, linking to processwire.com, writing PW modules/templates/code to share, helping to find and nail bugs, getting involved in the code, etc. So I guess that translates to anything you are interested in towards improving the project or sharing it with others. But of course, nothing is expected or required.
-
It sounds like you've now got both the first() added and the single image fields. You want one or the other, not both. The first() was just to grab the first image from an image array. If you have the field set to contain a max of 1 image, then it's just going to have that image, and no array. So if you are going to keep the "first()" in there, then change it to a multi-image field (set the max to 0 or greater than 1). If you want to keep it a single image field, then get rid of the "->first()". If it still doesn't work, we need to take a closer look because the error message you posted sounds like work_thumb may not be a variable on the page (or there may be no image attached). One thing you can do is: var_dump($web_work->work_thumb); Just to see what it is. I'm guessing it's null, and it's coming from a page with no image attached. Another thing you might want to do is place some more limits on your $pages->find(). Right now it's pulling all pages with the work_web template, no matter where they are. There's no problem with that, but it might be pulling a page you've forgotten about somewhere else in the tree. I would suggest something more specific: $work = $pages->find("parent=/work/projects/, template=work_web, sort=-date"); Or: $work = $pages->get("/work/projects/")->children(); // assuming all children use work_web template Or: $work = $pages->get("/work/")->find("template=work_web, sort=-date");
-
I've just depreciated the Textformatter::format($str) function in favor of Textformatter::formatValue(Page $page, Field $field, $value). I guess I didn't consider the things we'd be using Textformatter for in the future. But it should be ready to go now. Just grab the latest commit and implement the 'formatValue' version rather than the 'format' version in your Textformatter module. You can now get the field name from $field->name. I see what you mean, though am surprised they don't provide built in capability to deal with single-line (titles) vs multi-line (textareas) markup. We could always strip paragraph and heading tags from the single line fields. So long as they are both dealing with the same kind of markup tags, I think we'll be fine here. Though not positive. I'm excited to see how this goes! Thanks, Ryan
-
I'm not sure how to reproduce the first issue you brought up. I've tried several times dragging trees into the trash and out again, but no luck. Please let me know if you are able to reproduce it again at some point. I was able to reproduce the second issue you brought up, which was a loss of status when trees as trashed all at once. It would just give them all a "trash" status, removing any previous unpublished, hidden or locked status they may have had before. I've just fixed this in the latest commit. Thanks for finding it! Sorry for the lost status in your tree. Btw, it can sometimes be dangerous changing stuff in the DB directly, outside of PW's API. It sidesteps several other things that occur when a page is saved. There are other tables involved in every $pages->save() so manipulating the data directly, even a simple parent change or status change, can cause problems. Not major problems, but still, it's best to try and make the change from the API. And if that still doesn't do it then post here and we'll figure out a safe solution.
-
Shane, it sounds like you have a multiple-images field rather than a single image field. Two ways you can solve it. First would be to convert to a single image field. Go in Setup > Fields, and edit your work_thumb (and work_full) fields. On the 'details' tab of each, enter "1" for "maximum files allowed". That will make your field dereference in the manner your code is written, making your code example work how you'd expect. The other solution is for you to change the first line in your foreach() to this: $image = $web_work->work_thumb->first(); You may also want to add a check to deal with pages that don't yet have an image attached, i.e. if(!$image) continue;
-
I'm not sure which solution we're talking about, because there have been a few posted. Can you post the code for the solution you were using? I'm guessing it would be an easy fix, but just need the context. The above will only cycle through the first 16 images on any page. Then it would move on to the next page in your $photos->children loop and display the first 16 photos from the next page. But it's not going to do anything for pagination. If you want to keep things from getting overly complex, I'd recommend either focusing on paginating the images from a single page (like the example below) or paginate multiple pages where each page has 1 image. I think we can find straightforward solutions for either of those. <?php $limit = 16; $start = ($input->pageNum-1) * $limit; $images = $page->images->slice($start, $limit); foreach($images as $image) { // ... }
-
Beautiful site Martin! Nicely done! Love the transparency on the trees, and the trees as a concept for your company name as well. You really have a fantastic portfolio here too. Thanks for posting this.
-
I can post one on Tuesday when I'm back in my office. I'm just on mobile till then.
-
No doubt we'll build this auto-publish or auto-unpublish as a module this hooks into LazyCron. When built, it will most likely be a core module, but one that's disabled by default.
-
In order to drag-move a page to another branch, you have to open that branch first (even if it has no children). Opening that branch is a matter of just clicking on the page. You know a branch is opened when you can see it's 'edit | view', etc. links. I think it would be nice to have it auto-open a branch when you hover over it for a couple of seconds, but that's beyond my current JS skill level.
-
This options are primarily for guiding the direction of newly created pages. They don't affect pages already in the system. So when you choose "require this parent" that means "require this parent when creating a page that uses this template".
-
You are right I think this coming week will be it. It would be this weekend, but it's a long weekend (with Labor Day tomorrow) and I'm not getting any computer time. But I think we should be ready by the end of the week.
-
I'm on a cell phone so some of your code example isn't coming through but put your publish_date selector in here: $notes = $pages->get("/notes/")->children("template=notes, sort=-publish_date, publish_date<$today");
-
Absolutely--You could definitely use a custom date field for this. And if you don't want them showing in foreach, then just specify a date range in your selector: $today = time(); foreach($page->children("date<$today") { ... }
-
If you need to select a lot of pages, you are right that it's cumbersome. But I had to design this field to maximize the simplicity with my clients. So the instant feedback of closing the list, showing you what was added and letting you sort right there was the preferable compromise. At least for the needs of the clients I work with. Eventually we'll make the behavior configurable where you can tailor it more to the needs of fields where you might have a lot to select.
-
Currently there isn't a way to change the published 'created' date, short of changing it directly in the SQL. PW only sets this field the first time a page is saved, and then doesn't include it in any future saves. Though I could certainly change that. But if you are working this weekend, here's how you could do it with SQL: <?php $page = $pages->get("/page/you/want/to/change/"); $time = strtotime("2011-04-23"); // or whatever date you want wire('db')->query("UPDATE pages SET created=$time WHERE id={$page->id}");
-
Actually we do need something like HTTP_X_FIELDNAME. Maybe not for this specific instance with file uploads… but in order for PW to support saving any field via ajax, it needs to know what it is ahead of time. Otherwise there would be no way to detect something like an unchecked checkbox. By that I mean that when you submit a form with nothing but an unchecked checkbox, the $_POST would be an empty array, no reference to the checkbox. So something like HTTP_X_FIELDNAME is actually quite a good idea, and necessary if dealing with individually POSTed fields within a form. The only thing I wonder about is: what is the advantage of using a header as opposed to a regular POST var for this? Might it be simpler for it just to be another POST var rather than a header (for simpler ajax with jQuery)? Something like a POST var called "_fieldName" that's a string with a field name or "_fieldNames" that's an array holding one or more field names. I only mention this because I don't yet know how to send headers like HTTP_X_FIELDNAME with regular jQuery, so am just looking for the most straightforward solution. Sounds good to me. That looks similar to what it already does. Currently this is what it returns: { "error":false, "message":"Saved page '1' field 'images'" } Whenever PW sees it's an ajax request, it just returns a JSON of any messages that you would usually see in the admin. That's how it gets error alerts to the PageList ajax, for example. What would you think about using the same format that's already there, but just adding a 'filename' field to it, like in your example? Like this: { "error":false, "message":"Saved page '1' field 'images'", "filename": "filename.jpg" } and { "error":true, "message":"Please no more photos of your cats.", "filename": "filename.jpg" } I also noticed when testing that I get this message from Firebug in Firefox 6 whenever the ajax upload code executes. It doesn't seem to matter or affect anything, but just wanted to mention it in case it makes any sense to you: Use of File.fileName is deprecated. To upgrade your code, use standard properties or use the DOM FileReader object. For more help https://developer.mozilla.org/en/DOM/FileReader
-
getFieldValue isn't hookable and won't be. It's used internally by the Page class, and not part of the external API. There is a little overhead with every hooked function, and getFieldValue is one that sees so much activity that making it hookable would potentially reduce performance. What I'll do instead is add a new hook that only gets called when $page->get(fieldName) or $page->fieldName is returning a null. That will enable us to achieve the same thing without adding much, if any overhead. We'll likely call the hook 'getUnknownFieldValue'. When a module hooks into that function, it'll get the opportunity to supply a value for a $page->fieldName call that would have otherwise returned null. For instance, if your page didn't have a 'body' field, and you called $page->body, it would return null. But in your case, you want it to potentially translate 'body' to 'body_fr' or 'body_en' or something like that, so that's where this hook would come into play. You could have a call for $page->body return the contents of $page->body_en rather than null. Also want to note that there isn't currently a hook like this. It's something that I need to add, but it will be easy to do. Of course– There won't be any change in syntax.
-
Good news, I got all the AjaxUpload stuff out of ProcessPageEdit and everything working with WireUpload, so now the AjaxUpload files get routed through there instead. It basically saves it in a temporary dir like PHP does with regular uploads, then creates a new $_FILES var cloning what would be in the PHP one during a regular upload. That way, not much code had to change in WireUpload and it's backwards compatible with regular uploads. It runs through all the same filename and extension validation and sanitization before getting moved to the destination dir and sent back to InputfieldFile. One thing I realized though is that we need some way to send a success (or error) response with the actual resulting filename back to InputfieldFile.js AjaxUpload. WireUpload sanitizes filenames, makes them lowercase, removes non ascii characters and so forth, so it may have changed the filename or thrown an error that ultimately needs to be output by InputfieldFile.js. I hope to get time this weekend to experiment with it more, but so far everything seems to be working great. I'm still adding a little more validation (for file size) but will post updated files once I've got that going, hopefully sometime this weekend. Thanks for all your work in getting this going. I can't wait to get this officially committed to the 2.1 source.
-
It's definitely not for everything. There are plenty of things we need to define custom styles for. I try to keep them all part of the admin theme for the most part, but of course those have to be general purpose, non-specific stuff. It gets tricky when you get down to modules with specific needs, especially with regards to color. One way I've been avoiding the issue lately is to use opacity. For instance, if I want something to be a little de-emphasized, I might add an "opacity: 0.5;" to the stylesheet, so that it'll continue to be de-emphasized (with the right colors) regardless of the admin theme. Not sure if this is the best approach or not... but it seems to work. Ultimately we may want to add more styles to theme stylesheets to cover more needs. Or could standardize on some style framework that compliments jQuery UI and takes a broader role. I appreciate any suggestions you have in this area. Good to know. I rarely had to deal with "undefined" before jQuery 1.6, but now it seems 1.6 likes to return undefined for everything it didn't before, so I suppose I'm getting to know non-jQuery javascript a little better now. Can you describe more or point me to a good link? I'm not sure I understand about the HTTP_X_FIELDNAME. I use 'ugly but unique' mostly for selecting in javascript or styling things that are completely unique to the module. Everywhere else the jQuery UI styles are probably better, but of course they don't cover everything. Perhaps we can collaborate on PW's common CSS framework to cover all the stuff that jQuery UI doesn't.
-
That's a good idea and I don't think there would be any worries about performance or overhead. But since there may be different approaches for multi language support, I'd probably want to delegate it to a module rather than make translation assumptions with field names. So we could add a new hook to the Page class that is called when an unknown property is accessed (a hook called when the return value is going to be null). Then a module could hook into it to see if it can translate it to another field. Using your example, the hook would get called when the unknown field "body" is accessed. The hook would check to see if the page has a "body_$lang" field (where $lang might be "en or "fr", etc), and return it if it does. Of course, that sort of thing could very easily become and endless recursion loop, so PW would prevent that.
-
Pete, I work on several travel-based web sites as well and they keep me in business. Good to hear you are working on these types of sites too–it's nice to have a peer in the industry! Perhaps we should collaborate on one of these projects someday. There seems to be an overabundance of work in this area, it's enjoyable work, and a lot of good people. Not specific to travel industry, but my experience has been that most sites that have a large inventory of constantly changing stuff in any industry are providing a means to share and mirror their data. Most often, they are using verbose XML feeds (well beyond something like RSS), and letting their vendors or affiliates pull data off of them. The type of data sharing I was describing in the other thread is really no different, and I would say that PW lends itself especially well to both sharing and pulling data. PW also makes it easy to go far beyond just providing a feed and instead providing a true web service that can be queried. It really is fun to do. I've done this on a few sites, and seen other sites do it too, so it's not a secret or anything. However, it does cross into a territory of getting logic involved in style, so not a best practice for those that like to just swap in new stylesheets to completely change a design. Lets use a fictional example where you want to display a wide horizontal row of 3 square photos and another vertical row of square thumbnails, 2 per row. For landscape orientation photos that have the resolution, you want to double the width to maximize the space. You'd treat the big horizontal row and the vertical thumbnails as two separate things, though might use the same code (in a function) to handle either. In either case, you need to know the total width of the row in pixels so you know how much room you have to work with. Then you'll keep a counter on the width of each photo so you'll know when you've filled the space. You'll also look for opportunities to maximize the photo width. Treat the following as pseudocode because it's typed in the browser and not tested: <?php $pixelsMax = 900; // max pixels we're allowed to use $pixels = 0; // counter of current used pixels $w1 = 300; // target regular size image width $w2 = 600; // target double size image width $h1 = 300; // target height $skipped = array(); // images skipped due to being too small, can be displayed elsewhere $out = ''; // where we'll store our markup while(1) { // if there's no more room for a small photo, then break if($pixels + $w1 > $pixelsMax) break; // shift off the first image $image = $page->images->shift(); // no image? then stop if(!$image) break; // get it's width and height $w = $image->width; $h = $image->height; // if the image isn't big enough, then save it and skip it if($w < $w1 || $h < $h1) { $skipped[] = $image; continue; } // get the current image width/height $w = $image->width(); $h = $image->height(); // see if there's room for a double-wide // and also if the image has a wide-landscape orientation if(($pixels + $w2 <= $pixelsMax) && ($w / $h >= 1.5)) { $newWidth = $w2; // double-wide } else { $newWidth = $w1; // square } // make the image the size we need it $newImage = $image->size($newWidth, $h1); // add to our width counter $pixels += $newWidth; // make the markup $out .= "<a href='{$image->url}'><img src='{$newImage->url}' alt='{$image->description}' width='$newWidth' height='$newHeight' /></a>"; } // stuff the unused images back to the page // so they can be used for the vertical thumbnails foreach(array_reverse($skipped) as $image) { $page->images->prepend($image); } This is all typed in the browser and untested, so there may be errors, but hopefully it at least works as pseudocode. If it were real code, we'd want it in a function too. Now the vertical thumbnails part would work in a similar manner. You could use the above as a function for each row of thumbnails, but may prefer to make something more efficient custom to the need.
-
Antti, I've been going through the code line by line just to see how everything works so that I can be of more help here. The code looks beautiful, you did an awesome job with putting this together. I've only made it through the InputfieldFile part so far and here are some comments/questions for core integration: In this line, I'm wondering about the css('color', 'white') because that may or may not be compatible with whatever UI theme is being used? progressBarValue.addClass("ui-state-default").css('color','white').html("<span>100% complete</span>"); Also on the line above, what do you think about replacing the word "complete" with a ui-icon-check or a ui-icon-circle-check, just so there's one less thing to translate in languages? Since this line is in the JS, it made me realize I probably need to make ProcessPageEdit so that you can post right to "./". Otherwise, the HTML5 upload will be harder to make use of outside of the PageEdit (for example, the new CSV import module has a file upload, and so having the JS post to /fields/ isn't portable). This is my fault of course, and I'm working on an alternative so that you can post to "./" rather than "./fields/" and will keep you up to date. xhr.open("POST", "./fields/?id=" + page_id, true); I was wondering about class names like "over" and "complete", and if it might be generic enough to conflict with some other future 3rd party module or customization that someone is using. If these are part of jQuery UI's built-in progress bar classes, then there's nothing we can do about it, so skip the next paragraph. Otherwise, here's a thought about class names created by modules: When it comes to the core, it might seem overly verbose, but I mostly try to use really specific names so that there's no possibility it could ever conflict with someone else's stuff. I figure I'll leave the short/simple names for non-core stuff. For instance, lets say someone builds their own new Fieldtype and they use class names like "over", "on" and so forth. If they don't scope them down far enough in their stylesheet, the "over" one could potentially affect the HTML5 upload styles. Like, lets say they had this in their stylesheet: .over { position: absolute; top: 0; left: 0; } Granted, that's their problem not ours, and you've properly scoped your styles in the CSS. But it's also one of those things that is easy enough to prevent with specificity. Examples might be: InputfieldFileHTML5Over and InputfieldFileHTML5Complete … verbose and ugly, I know. But I just wanted to mention this and you decide whether it's worth it. I don't know my way around JS near as well as PHP, so had a question on this line: if (typeof files !== "undefined") { If I recall correctly, I usually see it like this (constant rather than string): if (typeof files !== undefined) { Does it work either way? On the following lines in the stylesheet, I'm wondering about theme conflicts when someone swaps in a new jQuery UI theme. Specifically wondering if any might work better as jQuery UI interaction states or interaction cues classes (http://jqueryui.com/docs/Theming/API) rather than defining specific colors. Also should mention that I'm occasionally defining some specific colors in some of the module-specific code in PW as well, but am trying to move away from it for better compatibility with new admin themes. .InputfieldFileUpload .dropHere { ... color: #777; } .complete { background: green !important; } .AjaxUpload .ui-progressbar-value { ... color: black; } .ui-widget-content.over { border-color: rgb(135, 167, 27); background: rgba(90, 200, 27, 0.1); }
-
$page->filesManager->path - doesn't return anything, it should be: $page->filesManager->path() - this works Sorry about this, I think I posted an example using 'path' rather than 'path()' earlier by mistake. The function version was required here. I say 'was', because I just updated the class to also support the non-function version too, so will commit that soon.