-
Posts
17,094 -
Joined
-
Days Won
1,638
Everything posted by ryan
-
I wonder if there is some mod_security setting that prevents HTML5 uploads from working at some providers. That's the only thing I can think of.
-
Joss, thanks for making this. Looks and works great! I've been thinking that we need site profiles that originate in a few of the different frameworks, so this is really a great place to start. A few minor points of confusion I ran into: I can't seem to click to the "About this site" or "About pages" except on the sitemap page. The top navigation only seems to let me get to the "child page example" pages. The prominent "read more" button doesn't seem to link anywhere. I couldn't find an "edit" link/button anywhere on the front-end to case navigating between front-end and admin. Something up with the site settings template (see attached screenshot). I'm thinking those TinyMCE fields might just need to span full width. Though since you've got 3 identical fields, this might even be a good potential use for a repeater? Also on those TinyMCE fields, the text seems to be running up against the left edge for some reason (see screenshot). Not specifically a problem, but a detail I figured I'd mention while I was making this list.
-
Well admin themes are a type of module themselves, in that they are modular and meant to be swapped easily.
-
Ability to provide custom cropping center to the ImageSizer
ryan replied to u-nikos's topic in Wishlist & Roadmap
I've added the crop percentage stuff to the dev branch if you guys want to take a look and try it out. Admittedly, I don't totally understand all aspects of this or even how to accurately test it. I did also try to add crop by pixels support (which is more tangible to me) but am not getting the result I expect so kind of gave up on it. Let me know if you guys can figure out a way to make it work. To crop by percentage, do it like this: $img = $page->image->size(400, 300, "50%,30%"); To crop by pixels (not currently working quite right) do it like this: $img = $page->image->size(400, 300, "100,100"); When doing testing or debugging, I recommend preceding your tests with a $page->image->removeVariations() call. I was testing with something like this: $img = $page->image; // remove any previously generated sizes, crops, etc. $img->removeVariations(); // output original echo "<p>$img->url<br /><img src='$img->url' /></p>"; // make crop $img = $img->size(400, 300, "50%, 30%"); // test crop echo "<p>$img->url<br /><img src='$img->url' /></p>"; -
Looks great! Thanks for making this admin theme. Some really nice details in there too. Please add to the modules directory at your convenience: http://modules.processwire.com/add/
-
I actually saw a DeLorean up close for the first time last week, in Orlando, FL. Drove out of a parking spot right next to me. Was surprised at how good looking the car actually is, and a lot lower to the ground, and not nearly as dated looking as I would have expected.
-
I think you'd probably want this, or something like it: if($input->urlSegment1 && $input->urlSegment2) { // URL has /category-name/post-name/ $postName = $sanitizer->pageName($input->urlSegment2); $post = $page->child("name=$postName"); if(!$post->id) throw new Wire404Exception(); $session->redirect($post->url); } else if($input->urlSegment1 === 'rss') { $homepage = $pages->get('/'); renderRSS($page->children("limit=10"), $homepage->get('headline|title'), $homepage->get('summary|meta_description')); } else if($input->urlSegment1) { // URL has /category-name/ $categoryName = $sanitizer->pageName($input->urlSegment1); $category = $pages->get("/categories/$categoryName/"); if(!$category->id) throw new Wire404Exception(); $session->redirect($category->url); } else { // display paginated blog list $headline = $page->get('headline|title'); $content = renderPosts("limit=10", true); include("./main.inc"); }
-
Thanks for your efforts here. I think it looks a whole lot better than the Underground logo. And I think they are plenty different enough, so that's not a concern to me at least. What is a concern though is something that Diogo brought up when I'd done something similar (though not as pretty as yours). He mentioned that the uppercase Avenir P by itself looked like a parking sign, exemplifying standing still rather than moving forward… something we probably don't want to communicate. Once he mentioned that, I couldn't un-see it either. Though maybe we're looking too far into it, and I'd be curious what others think.
-
Form Builder doesn't get involved with individual fields (other than a custom files field made for it). So it will reflect whatever behavior is provided by the Inputfield modules installed on your system. I'm not aware of any Inputfield modules that provide the capability you mentioned yet, but it's certainly feasible. Multi-page forms are not currently supported, though on the roadmap. Some basic conditional logic will be added to ProcessWire's Inputfield system within the next couple of versions, so Form Builder will inherit the same conditional logic at that time. However, it is currently possible to support conditional logic on your own with javascript manipulation of the form. There are several instances in the PW admin where this is being done with Inputfields already.
-
Best bet is to delete the files you intend to replace by clicking the trash icon and then save. Then upload the new replacements.
-
ProcessWire is a content management framework, which is still a "framework", but more focused on a particular thing. Whereas the framework scope of CakePHP, Laraval, CodeIgniter, etc., is more broad and cover more territory. ProcessWire isn't meant as a replacement for one of those frameworks, but I think there are probably many instances where its focus might make it preferable. And an equal number of instances where the opposite is true as well. There's also something to be said for bringing the two together in some instances. Another big area of difference is that traditional frameworks enforce a particular approach to build on top of, whereas ProcessWire aims to be a lot more transparent, like jQuery. Frameworks set you up with a place to put your models, views and controllers, whereas ProcessWire puts in you in a plain PHP file (template file) that is given a location context ($page) and lets you take over from there. We think MVC is a good approach to take with ProcessWire template files, but don't enforce anything, as it's up to the developer. For better or worse, the possibilities are wide open in the same way they are with a PHP file on its own… though with a full CMF API at your disposal.
- 27 replies
-
- 12
-
-
(Static) Template page for failure to connect to DB
ryan replied to BrendonKoz's topic in Wishlist & Roadmap
Sounds good, I am putting this in 2.3 and should be on the dev branch later today. It will look for a file /site/templates/errors/500.html and use it when present. -
Another factor to consider with the current solution is that it depends on an autoload module (executed on every request). That's a little less efficient than a solution that is specifically called upon when needed, as an Inputfield would be. From that respect, it would probably make sense for this to be InputfieldTextareaCounter. It would also be the simplest and most straightforward to implement and maintain. The drawback would be that you couldn't apply the counter functionality to other types of unknown future textarea derivative inputfields. But if someone is making a new text inputfield, chances are it's like TinyMCE, ACE editor or some other type of thing that wouldn't be compatible with the counter anyway. Ultimately the functionality provided here is pretty darn useful regardless of how it's implemented. But if I were implementing it myself, I'd probably make it an Inputfield rather than an autoload module. As a bonus, this would also guarantee compatibility with non-admin Inputfield forms, like those from FormBuilder, FormTemplateProcessor or API generated Inputfield forms.
- 67 replies
-
- 4
-
-
- Inputfield
- UI
-
(and 2 more)
Tagged with:
-
I don't know of a way to have ProcessWire keep track of two separate template directories. But of course you can turn any template file into a controller for any number of other template files and include them from wherever you want. A simple example would be to create a template called "external" and add a text field to it called "external_file". Then in your external.php: <?php if($page->external_file) { $filename = "/some/external/path/" . $sanitizer->name($page->external_file) . ".php"; if(is_file($filename)) include($filename); else echo "$filename does not exist"; } else { echo "No external file defined"; } Rather than external_file being a text field, it'd be better as a page reference field connected to a <select>. That way you could select your template rather than having to type it in. But I wanted to keep this example as simple as possible.
-
Thanks Joss, this is really coming together very nicely!
-
If switching the salt to 22 digits fixes it, I'm all for that! I'll make this update. Thanks again for all of your research and testing there. This is interesting, it seems like your web host must have sessions configured to do something different than usual as PW has no memcache implementation for sessions yet. You might try installing the SessionHandlerDB module that comes on the dev branch to see if that resolves it. Your session_start(); at the top of index.php may be leading to other less apparent problems, so I would try to get it working without that if you can.
-
Custom string in names of database tables
ryan replied to Michal Gancarski's topic in Wishlist & Roadmap
If one had a big enough security hole in the site where someone could actually execute SQL queries, then that's something that probably needs to be fixed quickly. Seems like trying to hide the table names is a good way to let a security issue drag on and perpetuate. I'd also worry that having such a feature in place would make developers assume they weren't fully responsible for their own security and could half-ass some code because "the random table names will protect me." Then again, if I was running WordPress or Joomla, I'd probably want all the security through obscurity I could get. I doubt the problem is the CMSs themselves, but the plethora of insecure plugins and themes. I suspect the masking of table names is in response to an existing problem with those. Still, it seems like this approach does foster an ecosystem of insecurity. If that wasn't a security "feature" then the bad plugins would get cast aside a lot sooner and the whole ecosystem would probably be more secure in general. -
Thanks that definitely looks interesting and useful. When we comes to these API functions, we're basically blind, so the cropping functions are really about trying to ballpark an area. We assume you may have a "group of images" context, but not a single image context. For instance, say you've got an employee directory containing a vertical head shot photo for each person. Then lets say you need square thumbnails for a listing page. In these thumbnails, you'll want to gravitate towards the "north" so that their head doesn't get chopped off. For other situations where you aren't blind and do have a single image context, then I think Apeisa's thumbnails module is the best way to go. Though the next step with the API may be to add more pinpointed cropping functions, but I suspect they will really only be useful for people developing a front-end to them for cropping individual photos.
-
Thanks for the follow-up on this. Those two statements should be equivalent and produce the same result. So if they aren't, then sounds like I need to do some bug hunting.
-
Interesting you are right, it is showing the old stacked logo in other browsers for me. I will attempt to fix. Luis is right, Process=Avenir and Wire=Mahalia. Those are the same two faces used in the round logo above too, except reversed (P uses Mahalia and W uses Avenir). --- Edit: everyone should now see the square logo. If you don't, you may need to reload:
-
Joss actually emailed me a similar question and I'll duplicate my reply here since it seems relevant: Performance as it relates to database is really not an issue that one needs to consider much (or at all) when it comes to creating their fields. Most field data in ProcessWire is loaded on-demand. It loads data selectively and only when it needs it. This enables it to be highly memory efficient with large quantities of pages in memory at once. When you have a $page, behind the scenes, none of the page data is actually loaded until you access it. For instance, if you access $page->body, then it goes and retrieves it at that moment (if it hasn't already retrieved it before). MySQL is extremely fast with simple primary key, non-joined selects, and we take advantage of that. What I'm trying to get across is that quantity of fields does not translate to an increase in joins or other factors that would slow the system down. Where ProcessWire does join data automatically is at page load time is when you check the "autojoin" box on a Field's "advanced" tab. Some fields you know will always be needed with every $page instance, and that's what autojoin is for. Typically, I make my "title" field autojoin, as it is already by default. I've hidden that autojoin option under the Advanced tab simply because most people never need to consider it. The original intentions behind autojoin have become less applicable than I originally thought [with regards to performance], so it's not something that comes up that often. ProcessWire also uses joins when it performs queries for $pages->find("selector"), and related DB-querying selector functions. It joins all the tables for fields that you query. So if you perform a find for "date>2012-12-19, body*=holidays" then it's going to join the field_date and field_body tables when a value matches. Though it doesn't do this for the purpose of loading the data, only for matching the data. Technically this type of query could be potentially faster if all those fields were in one table. But that doesn't translate to results that matter for us, and doesn't affect the way that you should use ProcessWire. The benefits of our one-table-per-field architecture far outweigh any drawbacks. I put a lot of time into finding the right architecture and balance here when coding ProcessWire 2. Incidentally, ProcessWire 1 did use the one-table approach (all the field data was stored with the page rather than in separate tables) and it was far less efficient with memory, and about the same in terms of performance. It's better to re-use something like "body" (when possible) rather than create "article_maintext" or other template-coupled variations like that. The reasons for that are for your own benefit. It is less to keep track of, and tends to foster better consistency. It also results in more reusable code and broadens the potential of where the data can be used. Take the example of an on-site search engine, like you see in the upper right corner of processwire.com. If we know that the main text field(s) of most templates has some consistency in their field names (like title and body), then we can write code that doesn't need to know whether something is an article, a press release or a product. We can find all pages that match "holidays" in the text just by doing this: $pages->find("title|body*=holidays"); But if created a separate textarea field for every template, then any code that queries those fields needs to know a lot more about them: $pages->find("title|article_maintext|pr_maintext|product_maintext*=holidays"); While that still works, it doesn't scale nearly as well. This also translates to the code you use to output the results. If you want to show a snippet of the matching text with the search results, you are going to have a lot more fields to consider than just "body". Now if each of your templates genuinely needs very different settings for each of their main text fields, then of course it's fine to create them as you need them. But in the real world, I think you draw more benefit by planning for reusability when possible. The benefits are for you (the developer), as it doesn't matter much to ProcessWire. Reuse fields where it's obvious that the name of the field makes sense in the context of multiple templates. If template "employee" needs a date_of_birth field and template "press_release" needs a date_publish field then just create one field called date and use it on both templates. On the other hand, if you need multiple date fields on the same template (like date_unpublish) then more specific field names start to make sense. In that case, I would usually use my date field for publish date, and create a separate date_unpublish field for my unpublished date field. Though some may prefer to actually have separate date_publish and date_unpublish fields because they are obviously related by name. Ultimately, use what works best for you, but always keep an eye out for obvious reusability potential with fields. I think that most people naturally arrive at the right balance for their needs after some experimentation. What is a best practice for one need might not necessarily be for another. So these are mostly general purpose guidelines and people should find what makes the most sense in their context. For the majority of cases, I think avoiding tightly coupled template and field names is a better strategy. TL;DR: It doesn't matter to ProcessWire what you do. Aim to reuse fields when you can and when it makes sense, for your benefit.
-
This was recently contributed by another user via a pull request, so it's currently undocumented (aside from here). I'll add this when updating the documentation for stuff in 2.3. Though these operators were added in the 2.2 stable.
-
Should be fairly easy to add session support. if($input->post->pass) $session->pass = $input->post->pass; if($page->album_password && $session->pass !== $page->album_password) { $page->body = $input->post->pass ? '<h3>Invalid Password</h3>' : ''; $page->body .= file_get_contents("./inc/login-form.inc"); include("./basic-page.php"); } else { include("./album.inc"); }
-
It should still be on the wiki, at least it is for me. I couldn't stand the PW logo split on two lines (how it was before), so had to change it to something and this was the best I could come up with. I pulled this up from the past and I know folks aren't crazy about it, but just needed a square logo until someone comes up with something better.
-
Since it appears that each post can have only one category, you could easily solve this by making your actual site tree represent the /posts/category-name/post-name/ structure. If the one-category-per-post status will remain for the future, then this would be the best approach. But if you want to stick with your current structure then here are a couple options: Option 1: For your /posts/ page template, turn on URL segments like Adam mentioned. But since you want the category to be included in the URL, that's going to be your first URL segment (not the post_name). it sounds like you want the post_name to be the second URL segment. So something like this should work: if($input->urlSegment1 && $input->urlSegment2) { // display the post $postName = $sanitizer->pageName($input->urlSegment2); $post = $page->child("name=$postName"); if(!$post->id) throw new Wire404Exception(); echo $post->render(); } else if($input->urlSegment1) { // display posts in category, or a 404 if you don't want it } else { // display regular content for your /posts/ page } If there is potential for post and category name collisions, you might want to precede the category part of your URLs with something like "cat-[category name]" for URLs like /posts/cat-widgets/post-name/. Option 2: If the goal is to avoid 404s, then I would take a different approach: accept the new URLs as they are in ProcessWire and perform redirects when one of the old URLs is hit. This would be more efficient than option 1, and you'd benefit from the newer shorter URLs. You'd do this in a similar manner to above, enabling URL segments for your posts template. But you'd take a different action: if($input->urlSegment1 && $input->urlSegment2) { // URL has /category-name/post-name/ $postName = $sanitizer->pageName($input->urlSegment2); $post = $page->child("name=$postName"); if(!$post->id) throw new Wire404Exception(); $session->redirect($post->url); } else if($input->urlSegment1) { // URL has /category-name/ $categoryName = $sanitizer->pageName($input->urlSegment1); $category = $pages->get("/categories/$categoryName/"); if(!$category->id) throw new Wire404Exception(); $session->redirect($category->url); } // if this point is reached, display regular content for your /posts/ page