-
Posts
16,772 -
Joined
-
Last visited
-
Days Won
1,530
Everything posted by ryan
-
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
-
Going to be without internet access for a few days
ryan replied to ryan's topic in News & Announcements
I'm down to 2 pages left in my "View new Content" tab! Good to see! In the past when I've left town, things quieted down a bit for a couple days. This time it did the opposite. I think we've reached a good critical mass here with the forum. I need to take more vacations now. You and Joss have very high post-to-like counts (aka: folks really like your posts). That means you should stop apologizing and we should thank you guys for your contributions here. But post and like counts are not a factor anyone here watches other than for a friendly high five. Unless someone is here to spam, they should post whenever they want. That's what this forum is here for. Keep posting as much as possible! The ProcessWire project is lucky to have you guys here. -
Looks like a cool technique Diogo! I've created custom admin page for clients to do various things. Usually I'll create a Process module to take care of it. But there have been a couple cases where I just wanted to do it with a template. In those cases, I've had it just use the site's template rather than the admin template, or alternatively just include() the admin template from my own. But will have to try this technique out next time.
-
I'm a little confused about the faceted search part, because [if I understand the example and terminology correctly] this is quite simple to do in ProcessWire at present. Here's an example from villarental.com that I coded in ProcessWire a couple years ago. I got there by clicking the terms in the left bar: Location: St. James Price: Up to $500 Bedrooms: 3 Features: Villas with Pool Of course, it doesn't let you select multiple items in each category, but that was by design (for ease of use, per client), not technical limitation, as it would be equally simple to implement. But there's nothing going on here except translating page references in URL segments to selectors. So when you guys mention facets as being a drive for something like Solr, what am I missing? I have no doubt that Solr can achieve these things at larger scale and more quickly than something like MySQL, as it's dedicated to the task. Though am thinking the audience that would benefit from this in ProcessWire may be limited. I don't think anyone has yet reached a scalability peak with ProcessWire where this would matter. Still, I'm interested in anything that enables us to scale further and faster and I do like what Lucene does. But because something like this may have a more limited audience, it's probably something we'd need to find a sponsor for in order to pursue in the shorter term. But count me as interested. The VisualSearch.js would tie beautifully to ProcessWire as the data source. Might be a good one to implement into the skyscrapers demo site.
-
Soma, this is great! I'm amazed how little code is involved in the module itself too. When are you going to start posting some of your new modules to the directory?
-
(Static) Template page for failure to connect to DB
ryan replied to BrendonKoz's topic in Wishlist & Roadmap
Showing a 404 is exactly what we do when there is a non-recoverable error like this (with guest user). But this is the one scenario where we can't. The 404 is a page like any other in the system, so if the DB is down, then we can't really retrieve anything at all. The DB is a vital organ. The only thing I can think of is that perhaps we could provide some custom predefined error template, perhaps /site/templates/errors/500.php that gets used instead, when present. But you'd have to assume the API was off limits, otherwise you'd potentially start an infinite error loop. -
Btw, I'm totally happy to go in and update these things if you'd prefer, but didn't want to go in and start changing stuff without running it through you first. You are way better at writing this stuff than me, so I didn't want to mess anything up. I've still got another 2 days before I make it through all the forum posts, so if anyone is wanting a Wiki account, please send me a PM, which I should get much quicker and can get you setup asap.
-
Joss, thanks for your outstanding work on the Wiki! I am making my way through it and posting comments on the "Discussion" tab of each as I go through them. Here's what I've got so far: http://wiki.processwire.com/index.php/Talk:Basic_Website_Tutorial And just one or two comments on these pages: http://wiki.processwire.com/index.php/Talk:Pages_Overview http://wiki.processwire.com/index.php/Talk:Page_Field http://wiki.processwire.com/index.php/Talk:Article_Listing_Page
-
Thanks for giving it a try Pete. Let me know if there's anything I can do to help too.
-
I've always liked the CodeIgniter docs too, though haven't had experience with the others, but they also look nice. I found this rather humorous though: http://ellislab.com/codeigniter/user-guide Note the lack of a trailing slash in the URL above (copied from onejegolders post). Click it, and then click "table of contents" and click on any item in there. You will get to a page with some Arnold video. Apparently EllisLab hasn't accounted for the trailing slash vs. non-trailing slash.
-
Marc, I've been out of town so sorry for not being able to reply sooner. Glad you got this figured out. Let me know if you find anything else is still not working here.
-
Tested here and works great! Thanks for making this Boundaryfunctions and Soma! I look forward to seeing this in the modules directory. This is a very useful module for sure. Minor point, but longer term, I wonder about the hooking method and whether that might present problems for future InputfieldTextarea derivatives. This one specifically excludes TinyMCE, but feasibly there are future others it might need to as well. It makes me wonder if this module might better exist as an Inputfield itself (InputfieldTextareaCounter) or perhaps as a module config setting where you check boxes for which Inputfields it should apply to. Or perhaps as a core addition to existing InputfieldTextarea. These are just ideas for the future, but seems like what you've got here now is working great and I look forward to using it!
- 67 replies
-
- 3
-
- Inputfield
- UI
-
(and 2 more)
Tagged with:
-
Validation for own Inputfield/Fieldtype modules
ryan replied to bfncs's topic in Module/Plugin Development
Fieldtype::sanitizeValue is the function that gets called every time you set a value to a page. So if you set $page->title = 'something'; then the value gets sent through FieldtypePageTitle::sanitizeValue before the value gets set to the $page. The purpose here is mainly to sanitize for type, potentially add some API setting convenience, and do it quickly. So a sanitizeValue() for an integer field would typically do nothing more than typecast whatever value is sent to be a integer. This function is not intended to be the place to sanitize/validate user input (Fieldtypes exist outside of user input context). Instead, this function is just here to make sure that whatever $page field you are setting does not end up containing the wrong type or something else obviously incorrect. If you want your Fieldtype to have some additional built-in validation or convenience here (to account for API setting of values), that's fine too. But this function is called every time a value is set to a page (whether you set it or PW sets it), so ideally it is fairly minimal and fast. Technically, implementation of Fieldtype::sanitizeValue is optional, but definitely recommended when getting into object-based values (like FieldtypePage::sanitizeValue, where it plays a pretty extensive role). Where you sanitize and validate user input is with Inputfield::processInput($input). That function literally takes the value from $input and populates it to the 'value' attribute of the Inputfield object. As an example, see the processInput from InputfieldText which is where we perform that regex validation. One thing you'll see in a lot of PW's core Inputfields is that we're actually doing the validation in the setAttribute() method, like in this example (again from the Text inputfield). In these cases, we see if the attribute being set is 'value' and if it is, we perform some additional validation on it. So whether the 'value' attribute is being set from processInput, or from the API, it gets validated in the same manner. This is the way to go if you want to validate both form input and values set manually, in one shot. But technically, you don't need to validate outside of processInput() unless you want to.- 13 replies
-
- 1
-
- inputfield
- fieldtype
-
(and 3 more)
Tagged with:
-
Also wanted to add this as a disclaimer for this forum: Any arrangement for work made via this board is a private contract between the individuals concerned. ProcessWire and Ryan Cramer / Ryan Cramer Design, LLC or any of its agents cannot be held responsible for the operation of that contract or any of the financial arrangements and will not get involved in any disputes under any circumstances. If it goes wrong for any reason, it should be sorted away from this community. Thanks to Joss for the suggestion and wording.
-
This is really great Joss! Thanks for all of your hard work here. What's the best way for me to send comments to you? Should I add inline comments directly in the wiki in some way, or post here, email or something else?
-
This is great Soma! Testing out here and seems to work beautifully. Please add it to the modules directory when you get a chance.
-
Great module Nik! I have updated the 2.3 (dev) to have that method hookable. I also made the redirectUrl an argument to the method, just to make it more useful for hooks. Tested out with your module and seems to work great.
-
Looks amazing Luis, I'm really impressed with this.
-
Quite a bit of validation options have been added to the Inputfield types since Form Builder was introduced. For instance, InputfieldInteger now supports min/max values and HTML5 number type. Text fields now support regex validation. Most of this is in the dev branch though.