-
Posts
16,793 -
Joined
-
Last visited
-
Days Won
1,540
Everything posted by ryan
-
Thanks Soma, I've brought this in and just testing locally so it should be in the dev branch very soon.
-
If include() works and include_once() doesn't, then it means the file was already included, so it got skipped the second time. The question is, when/where was it included?
-
I see what you mean. Row quantity really isn't a problem so long as the indexes are good. So I suspect even a single table would scale just fine. But if you still prefer a file-based storage option, using the existing $page->filesManager->path might be a good place to do it, as ProcessWire will maintain one directory per page (i.e. /site/assets/files/[id]/. You wouldn't want the version files to be publicly accessible, so you'd probably want to put them in filenames that PW prevents direct access to (like .php). Either of these seem like good options too. One table per field would be consistent with the way PW stores its fields... though that's for DB-related reasons that wouldn't apply to the case we are talking about. I guess the main benefit of splitting things into separate tables per field or fieldtype would just be to allow the possibility of versioning different data types. But your table with the single mediumtext column still allows for it, because all PW field data stored in the DB can be reduced to an array or JSON string: $data = $field->type->sleepValue($page, $field, $value); // convert to array $json = json_encode($data); // convert to JSON string Once it is stored as a string in the DB, then it's no longer "findable" except by possibly a fulltext index. But it seems like these versions probably would not need to have that search accessibility for storage anyway. I think you've got a lot of good ideas here. Though I'm not sure that you necessarily need anything more than what you've already got, with regards to data storage. From what I can tell, the data doesn't need to be selectable by anything in the data itself... just indexed attributes of the data: page_id, field_id, user_id, date. That combination would always be unique regardless of row quantity. It doesn't seem like you'd ever have to worry about potential for "full table scan" in MySQL. But there may be things I'm not thinking of. I haven't had my morning coffee yet. I do agree that splitting tables by fieldtype or field sounds better… but I don't know if it would ultimately matter. It would be interesting to take a table with 1m rows and a field_id index, and compare that to 10 tables with 100k rows and no field_id index. Assuming just straight selection from the table by page_id (no joins) and date-sorted results, would it make any difference? I have a feeling it would not, but haven't tried. But having it in one table you could select all field versions for a page in 1 query and your date-based maintenance could do its thing in 1 query. From a scalability standpoint, probably the only thing it would need there is just some limit on the number of versions it would load at once [25, 50, 100]? I'm assuming it doesn't load the actual version "text" here (it looked like you were doing that with ajax), but just the attributes. So maybe it would just need some kind of pagination or "older versions" link that loads the next block of [25, 50, or 100]. Either that, or you could just have version 1.0 say "we will store a maximum of 100 versions and no more", which would probably be fine for 99.9% of folks. No pagination worries. I think this is what the 37signals guys would say to do, at least for version 1.0.
-
Thanks for your continued updates to this translation pack. I think this is the most complete translation pack available! I have made the text in the Comments modules translatable, and am just doing a little more testing here before pushing to the source. But they should be there soon.
-
Is this site ready to announce and link from the main site? Let me know when...
-
@apeisa did you get a chance to try this one out?
-
Wanze, the latest commit should fix that bug.
-
How about: "Using URL segments to disconnect presentation URL from structure URL" or just "Real-world URL segments example" I'm not sure breadcrumbs need to be here, as that gets into specific implementations and not every site uses breadcrumbs. An individual's solution would just be to make the breadcrumb generation code aware of URL segments. // $page lives in /products/ and we want to show it in /categories/[first-cat]/product/ if($page->template == 'product') { // we need to base our breadcrumbs off some other page $parent = $page->categories->first(); // where categories is a page reference field held by product pages $parents = $parent->parents->prepend($parent); } else { $parents = $page->parents(); } // generate breadcrumbs foreach($parents as $parent) { // ... }
-
I'll assume you are logged in as superuser, just to rule out the possibility this is the result of access control. Check the template used by 'subpage' (Setup > Templates > that-template). Click the "family" tab. Make sure that template is allowing children. The lack of a "new" link would usually indicate the template doesn't allow new children, or that the allowed child templates have some setting on their Family tab that prevents them from being utilized there. Let me know if it still appears incorrect after reviewing those family settings? If so, try editing "subpage" and clicking the "children" tab. Do you have an "Add New Page" button?
-
$pages->get("name=mypage"); isn't a very reliable thing to do just because that query is within the scope of your entire site. Page names are only guaranteed to be unique within the same parent. So you'd be much better off doing one of these instead, which would be guaranteed unique: $pages->get("/path/to/mypage/") ... // retrieve by page path $pages->get(123) ... // retrieve by page ID Since the 'name' is guaranteed to be unique within the same parent, it would be perfectly fine to do this though, where $page is some page with children: $page->child("name=mypage")
-
Joss, that example you put in there is comprehensive enough that it probably belongs on it's own page in the Wiki. Thanks for putting it together. It's a rather nice tutorial in its own right. Is it possible to move it to a dedicated page?
-
Thanks for the PR Soma. If you solved this one, I owe you a beer (or a case of beer).
-
I think nateronn also mentioned this before. This will be one of the major drivers behind ProcessWire 2.4. I'm only concerned about actual bugs at this point for the 2.3 release. But it's a valid point and will make this look nicer soon. If using the same one as before, you didn't actually change the password. In this case, it literally needs the password to be changed.
-
Module - Shop for Processwire - Selectable options and the cart
ryan replied to NooseLadder's topic in Modules/Plugins
if("$page->children->product_size") { This is not a valid statement, in PHP or in ProcessWire. If it were valid in ProcessWire, then you could just remove the quotes and it would work. Either that, or you could surround it with "{$page->children->product_size}". However, there is no "product_size" property of PageArray, and $page->children is a PageArray. I'm thinking that maybe you meant this? if($page->child("product_size>0")->id) { -
Error: Unable to Generate Hash when trying to login into Admin
ryan replied to sam's topic in General Support
You should be able to get more detail by checking your log file: /site/assets/logs/errors.txt The ideal situation would be to upgrade both to PHP 5.4. But if you can't upgrade the production environment and don't want to downgrade your dev environment, you could set that supportsBlowfish() function in Password.php to always return false. However, I would look at finding a way to get the production environment upgraded because ProcessWire 2.3 is likely the last version that will work on PHP 5.2 (though that's not yet certain). -
The exception that you got there would be a bug. I must have broken something during some recent updates to make it pass Nik's test suite. I'll investigate further. But I don't think this is related to your question. You should be able to target the value for a specific language like this (assuming I didn't break that too) $pages->find("title.data$user->language=something");
-
Creation of markup and CSS isn't technically a design task in the traditional sense, unless the designer literally designs in markup and CSS (a trend I like). Perhaps that comes from the places I've worked, but front-end development was always a development task. The designers dealt with concepts and visuals, not code (markup, css, Javascript and template engines are all code). I think there is more of a blurred line now though, that's a good thing… I've always liked having my hands in both. But I work with a few design firms that outsource development to me, and all provide me with layouts (whether photoshop or some kind of flat image type). I've never had a designer provide me with code... though maybe my experience is isolated there. Photoshop is both a design and development tool. I don't know many web developers that can do their job without some kind of image manipulation tool like Photoshop. So I would disagree with "I should not need a copy of Photoshop to develop". But I know different companies do it different ways. If you've got designers doing front-end development, that's great, but they are working with code, doing development. If they are producing good quality markup and CSS, and really know how to design, they are a "web designer/developer". That term is what defines most of our audience here. Your company should give those designer/developers a raise. So lets say that's your workflow. I agree with Diogo that this sounds healthy… so long as the designers know their front-end code as well as a dedicated web developer. The "logic" that people use in ProcessWire templates is largely presentational logic. If you are trying to follow an MVC pattern, presentation logic is still a component of the view layer. I think this distinction is important. ProcessWire is already handling the business logic. It doesn't really matter whether you are dealing with a PHP API or a template engine, as the tasks are going to be the same. ProcessWire templates can also be used for business logic. Typically we don't want to be processing forms, saving pages, etc., in the places we are generating markup for output, even if you technically can. There are a lot of good approaches one can take to separate concerns. If using an MVC approach, then you would isolate your presentation logic and markup to a separate view, like we do with the Blog profile. (Though in the Blog profile we really do this more for demonstration purposes, as there's not much in the way of business logic.) If you take this approach, you are using your ProcessWire templates as controllers and dedicating other files as views. You can use the TemplateFile() class for views, as the Blog profile does, or you can use some other template engine like Twig, Smarty, etc. I think that this approach may provide the right balance of separation for the environment you've described. But I'm not sure it's worth the overhead unless building some real business logic (like an application) rather than a traditional web site. I'm not sure about the Smarty module, but the Twig module seemed to have the entire PW API available to it.
- 74 replies
-
- 1
-
- template engine
- twig
-
(and 8 more)
Tagged with:
-
I think that all the things you mention sound good. A few questions comments though: What would be the benefit of saving content to disk (vs database?). I'm not sure that it really matters to the user where it is stored, so wanted to inquire more about your thoughts here. What would define old entries? I'm guessing in some cases, people would like to just let it go forever (disk space is cheap). Javascript diff feature sounds awesome. Though also have to admit, just being able to toggle between the different versions and see the immediate change (the way you have it working now) is kind of a nice "diff" effect too. You don't necessarily need anything else for a version 1.0. How does it scale? Meaning, what happens when you've got 100 versions. I haven't tried it yet... and maybe you've already figured this out. But I was thinking maybe it shows the most recent 10 edits when you hover the icon, and ajax/paginates them somehow after that? (or opens a modal to a dedicated Process when you click more?) How does one handle deleting versions? I was thinking it doesn't need to be manual or interactive, but just a global time or quantity setting, i.e. "only keep last 50 versions" or "only keep versions for [n] days" or something like that. But having the option to keep them forever is also good… perhaps the behavior when the "[n] days" is left blank. Just supporting text fields for a 1.0 version seems ideal. This probably covers the vast majority of needs. Versioning of files/images sounds fun, but you are right that it's an entirely different task on the development side, since it has to manage files. And these fields aren't just files, but sort order, description, tags… and more in the future. Probably too much work for too little value here. So if it were me, I would just focus on those text fields. I think that the vast majority of versioning needs for files/images could probably be covered just by a file "trash" (whether global or page specific) where one could retrieve old files if they ever needed to… but that would be a different module. To summarize my thoughts: you've already got something great here that is already hugely useful. I'm not sure what more you need to take it beyond proof-of-concept (seems quite functional as-is), but the only thing I would consider is just making sure it can scale time and quantity. And then get version 1.0 out when ready. I think a lot of us can't wait to start using this. If there is anything that I can do to help (code, testing, etc.), I'm at your disposal.
-
Yes, I think this makes sense. I'll duplicate them there.
-
Sounds good, I'll setup a default here.
-
Wanze's example is just demonstrating a bit to get you started. You can hard code as little (or as much) as you want. When we present examples here, it's sometimes easier for people to follow if we hard code some things to make the context clear. But that doesn't mean you have to (or should) do that in your own implementation. Basically, we're trying to teach rather than do it for you, so that you can apply what you learn in a much broader context. In addition to the API page Wanze mentioned, you might also want to look at the /site/templates/sitemap.php file in the default profile. This demonstrates creating a navigation tree for an entire site, and may serve as a good starting point for what you are trying to do.
-
That error just indicates that there is a name collision when creating a new page. In this case, there is already a page called mariestads-julebrygd and it's trying to insert a new page with the same name (in the same parent). All that would need to be done here is just to make sure that the imported records are unique in whatever is being set to the $page->name field. If there is an ID column of some sort in the XML source data, that would be a good one to use for a $page->name field.
-
How to package a site to install it on another machine?
ryan replied to demhan's topic in Getting Started
It sounds like you've got a page that needs to be deleted. In your page list, go to: Pages > Admin > Setup > export-site-profile …and delete it. -
So long as that variable is in a double quote string (or concatenated to the string). PHP doesn't parse variables in single quote strings. If the variable you are putting in might have characters that could conflict with selector strings (like commas, or |) surround the value in single quotes. like something='$something'. If the variable is coming from user input, be sure to sanitize it. For a string, you'd want to use $something = $sanitizer->selectorValue($input->post->something);