Jump to content

ryan

Administrators
  • Posts

    16,715
  • Joined

  • Last visited

  • Days Won

    1,516

Everything posted by ryan

  1. Once 2.4 is ready and LanguageSupportPageNames is labeled as stable (it may be there already), I'm going to revisit the whole Multi-language documentation section, as LanguageSupportPageNames does change a lot with recommended approaches. I also just [last week] launched an update to http://www.tripsite.com that uses LanguageSupportPageNames, over thousands of pages and 5 languages. Previously it was using the multi-tree approach. It vastly simplified the underlying code of the site, and their editors are so much happier with this setup. The URLs are still mostly English (reflecting the previous names), but at least now it's up to them to decide what the URLs should be in each language. The PagePathHistory module is installed, so that whenever they change a page name, the old URLs will continue working. For instance: English: http://www.tripsite.com/bike/tours/around-venice/ Dutch: http://www.tripsite.com/nl/fiets/tours/rondje-venetie/ Dutch (old URL): http://www.tripsite.com/nl/bike/tours/around-venice/ Now making multi-language sites is so much more fun... I just wish I had more projects that needed it like this one! Hopefully the next major upgrade to this site will be to go responsive.
  2. The exception is coming from Yii rather than ProcessWire, so it's probably a question we can't answer here (unless someone here is an experienced Yii user). But it looks to me like Yii has a controller that is monitoring the request URI "/blast/" and trying to run a Blast::index() method or something like that. Basically, it looks like Yii's version of a 404. You probably need to somehow turn of its URL-to-function mapping, or tell it not to handle the request.
  3. This hasn't been asked, but wanted to cover how the permissions and publish workflow work on the site. It has a very simple, though nice setup, where authors can submit new posts but can't edit already published posts, nor can they edit unpublished posts by other authors. It enables Mike to have full control over any content that gets published on the site, while still allowing easy submission and edits for the authors. Post workflow All of the authors have a role called "author" with page-edit permission. On the "post" template, the boxes for "edit" and "create" are checked for this "author" role. This site also makes use of the page-publish permission, which is an optional one in ProcessWire that you can add just by creating a new permission and naming it "page-publish". Once present, it modifies the behavior of the usual page-edit permission, so that one must also have page-publish in order to publish pages or edit already published pages. The "author" role does not have page-publish permission. As a result, authors on the site can submit posts but can't publish them. Nor can they edit already published posts. In this manner, Mike has final say on anything that gets posted to the site. Post ownership The default behavior in ProcessWire is that the Role settings control all access... meaning all users with role "author" would be able to do the same things, on the same pages. In this case, we don't want one author to be able to edit an unpublished/pending post created by another author. This was easily accomplished by adding a hook to /site/templates/admin.php: /** * Prevent users from being able to edit pages created by other users of the same role * * This basically enforces an 'owner' for pages * */ wire()->addHookAfter('Page::editable', function($event) { if(!$event->return) return; // already determined user has no access if(wire('user')->isSuperuser()) return; // superuser always allowed $page = $event->object; // if user that created the page is not the current user, don't give them access if($page->createdUser->id != wire('user')->id) $event->return = false; }); Planned workflow improvements Currently an author has to let Mike know "hey my article is ready to be published, can you take a look?". This is done by email, I'm assuming. An addition I'd like to make is to add a Page reference field called "publish_status" where the author can select from: DRAFT: This is a work in progress (default) PUBLISH: Ready for review and publishing CHANGE: Changes requested - see editor notes DELETE: Request deletion Beyond that, there is also an "editor_notes" text field that only appears in the admin. It's a place where Mike and the author can communicate, if necessary, about the publish status. This editor_notes field doesn't appear on the front-end of the site. All this can be done in ProcessWire just by creating a new field and adding these as selectable page references. That's easy enough, but I want to make it so that it notifies both Mike (the reviewer) and the author by email, every time there is a change in publish status or to the editor_notes. This will be done via another hook in the /site/templates/admin.php: wire()->addHookAfter('Page::saveReady', function($event) { // get the page about to be saved $page = $event->arguments(0); // if this isn't a post, don't continue if($page->template != 'post' || !$page->id) return; // if this post wasn't made by an "author" don't continue if(!$page->createdUser->hasRole('author')) return; $subject = ''; $message = ''; if($page->isChanged('publish_status') || $page->isChanged('editor_notes')) { // the publish status or editor notes have changed $subject = "CMSCritic post publish status"; $notes = $page->isChanged('editor_notes') ? "Notes: $page->editor_notes" : ""; $message = " Title: $page->title\n URL: $page->httpUrl\n Status: {$page->publish_status->title}\n $notes "; } else if($page->isChanged('status') && !$page->is(Page::statusUnpublished)) { // page was just published $subject = "CMSCritic post published"; $message = "The post $page->httpUrl has been published!"; } if($message) { $reviewer = wire('users')->get('mike'); $author = $page->createdUser; mail("$reviewer->email, $author->email", $subject, $message); $this->message("Email sent: $subject"); } }); Mike, if you are reading this, does this sound useful to you?
  4. Just pushed some updates (dev) to the output of "who can access this page" on the PageEdit screen. Not sure I've got it perfect yet, but found a couple issues there related to what you mentioned and fixed them.
  5. I can't seem to duplicate this one. I give a role page-edit permission, go edit a template, on the access tab check all the boxes for that role and save. Then I go back and edit the role and remove edit permission. When I go back to the template access tab, no boxes are checked except for 'view'. So it looks like what I thought was a problem with cached permissions there isn't actually an issue. But I'm guessing I'm going about the wrong way in trying to duplicate it? Please let me know what steps to take and I'll try again.
  6. Once a system has a page-publish permission, it changes the behavior of page-edit as well. From that point forward, a user with page-edit permission must also have page-publish permission in order to edit a published page. The "who can access this page?" screen is telling you as much as it can about individual roles, but it's not telling you anything about combinations of roles. If a page is published, and there is a role that has page-edit, but not page-publish, then it's going to say it's not editable by that role. And that's true, because if you take that role by itself, the page isn't editable. Likewise, if you've got a role with page-publish, but not page-edit, a user with that role by itself can't edit anything. So this information section can't tell you anything about what might be the results of combining roles. Since that is determined at runtime, specific to a user, the only way you can tell is to try it with an actual user. Before I experiment too much here, I should check if you are testing by logging in as the user, or just by looking at what this info screen says? Stacked permissions should still work for the actual user at runtime. Though let me know if you find they aren't? These settings are cached with the template. So it may say one thing here based on that cached state, but again the runtime result of the actual permissions for a user should be consistent with the user's actual permissions. Let me know if you find it is not, as that would be a bug. I agree this must look confusing. Those checkboxes are getting populated with the cached value from the template. It sounds like what I need to do here is prevent "disabled" attribute checkboxes from having a checked value.
  7. That's the intention: to limit voting to people that are qualified to answer. People that know and are enthusiastic about a product take pride in being able to answer questions like this. I'm thinking that most in our community would be very enthusiastic about answering these questions, and I'm guessing the same goes for other products that people are enthusiastic about. On the other hand, my Mom's mothers club, Soma's high school buddies, Diogo's cousins and Antti's neighbors that arrive there from Facebook with the best of intentions to support ProcessWire (even if they don't know what it is), will get scared off, or at least answer honestly, because they don't understand the questions. IMO, that's a good thing that encourages quality over quantity (with apologies to my mom, Soma, Diogo and Antti's Facebook friends and of course the mothers club). There's also the selfish aspect: I think ProcessWire can compete with much more widely known projects like MODX and Concrete5 when dealing with qualified users of the product. But once bigger projects get their casual social networks involved, we would be outgunned. And the easier the questions are to answer, the more outgunned we might be. I'm guessing the most controversial question I mentioned is probably the one asking for a URL to a site running in the CMS. While that would be a great qualifier, I think you'd still derive benefits in quality, without much loss in quantity, from any questions that ask about the user's experience with the CMS: 1. How many sites have you used with this CMS? [ ] 0 [ ] 1 [ ] 2-3 [ ] More than 3 2. How have you used the CMS? [ ] As a web developer [ ] As a web designer [ ] As an editor (you edit content using the CMS) [ ] As a user (applies to forum software only) [ ] I have not used it 3. What is your favorite feature of this CMS? [Text field] 4. Enter your email address You'd accept the submission, but ultimately exclude the vote from counting if any of these conditions are met: 1. They answer "0" to question 1. 2. They answer "I have not used it" to question 2. 3. They answer "I don't know" or some other meaningless response to question 3. 4. Their email address or IP address matches one for a vote already taken. As a bonus, you'd have the option (if you wanted it) of filtering results by user type (web designer, developer, etc.), experience level with the CMS, and the ability to highlight the most liked features of some products. Meaning, questions like these aren't just about qualification, but about giving you more options with filters and views into the data, now or in the future. These are all just ideas and my opinion only. You've of course got my support and enthusiasm regardless of what direction you go with the voting.
  8. Actually, I'm not thinking. We already have date sorting in the Options section (which sorts at the DB level) so the column heading in this case doesn't matter for date sorting... or at least isn't that useful for it. I can make this date format configurable without any concerns.
  9. ryan

    Hanna Code

    It sounds like your version of MySQL won't accept default values for a text field. I've not heard of that before. Perhaps it is some MySQL setting that I've not seen before. Seems like if it won't accept a default value (which we specify a blank string) then it could only be null as a default. Not that it matters much, but I'd prefer the blank string since there is no use for a null here. I agree that removing the default that you did shouldn't cause any issues. I'm curious to see if this issue turns up for anyone else.
  10. I think that supporting multi-day events would just be a matter of adding an end_date field, and consider the existing date field a start_date field. Either that, or you could use a "number of days" field instead of an end_date, but I think having distinct start_date and end_date fields is better because they can support a time component, and they can be queried more easily.
  11. This is planned, just haven't yet found the time to implement it.
  12. The way you describe it, it definitely sounds like something isn't working right with the database then. If you have the opportunity to upgrade, that seems like the right thing to do.
  13. Just add something like this to the top of your events index page. You could compartmentalize this into a LazyCron call, but for such a simple thing it's really not necessary. $events = $pages->find('parent=/events/, date<"-3 months"'); foreach($events as $event) { $event->of(false); $event->addStatus(Page::statusUnpublished); $event->save(); } Btw, when testing something out like this, always comment out the $event->save(); the first time and take a look at what pages get affected by echoing them rather than saving them, the first time around. i.e. // $event->save(); echo "<p>Unpublishing: $event->url</p>"; Once confirmed that it is behaving the way you want, then remove the echo and uncomment your save();
  14. I'm not really sure what could be causing that. Apache and .htaccess know nothing about URL segments... that is only a ProcessWire term. To Apache/.htaccess those URL segments are just a part of the REQUEST_URI like anything else. I would comment out that directive in your .htaccess and look elsewhere (in your .htaccess and in your PW templates) to see where the redirect might be coming from.
  15. I understand what you are trying to do, but can't currently think of a way you can do it (at least not in any straightforward manner). Even if you could do it from the CSS side, there are other factors like sorting (which is designed to work vertically), and the add new items actions, etc.
  16. I think that you are on the right track using Pages rather than Repeaters for your sections. Actually, it looks to me like all of this stuff is intended to be output as pages on the front-end anyway, so you may want to avoid using Repeaters entirely. Repeaters are great for specific use cases, but you are far better off using Pages when it comes to anything site-structure related. If I've misunderstood the need to use repeaters here, then one solution you could look at would be to simply include your section_header field in the year_wrap repeater, and specify in your field description that the user should only specify a section header when they want to change it, and to leave it blank otherwise.
  17. There may be a way to do it from the SQL side, and that would probably be a good use case for using an SQL query rather than a selector. I don't currently have plans to make selectors support that level of query, as it's a pretty rare need (this being the first time it's come up). When a query needs to perform a currency conversion (and this is something I've had to do), I perform the currency conversion first, and then use the converted value in the selector query. That actually reminds me that I have a currency conversion module that I need to finish up and post soon.
  18. Awesome Nikola! I really like this module. Just a few suggestions: The module should not extend Process since it's not an admin process. Instead it should extend WireData. The module should not be autoload since it is loaded from an API call instead. Ideally the module would be called MarkupWeather or MarkupYahooWeather, since the "Markup" prefix is recommended for all markup-generation modules. Please add it to the modules directory as soon as you get the chance. It's a lot simpler to do now, as the modules directory pulls most stuff right from your GitHub page.
  19. While you may be able to use some of these syntactic tricks when it comes to setting a value, I think it's better to treat a Page as a Page and a PageArray as a PageArray, just as a matter of keeping your code readable. If I have code that needs to deal with either a Page or a PageArray, but it doesn't know ahead of time which it will be, I usually treat it like this: if($value instanceof Page) { // treat it as a Page } else if($value instanceof PageArray) { // treat it as a PageArray } Or I normalize it to one or the other. For instance: if($value instanceof Page) { $a = new PageArray(); $a->add($value); $value = $a; } // now we can assume $value is always a PageArray
  20. Testing here on a TextareaLanguage field, I also wasn't able to duplicate the issue. Do you have any other 3rd party modules installed? If we can't determine why it's exhibiting the behavior there, you probably just want to turn off autojoin for that particular field. There's not a lot of benefit to using autojoin, particularly on a multi-language Textarea field. On most of my sites, I only have 'title' autojoin.
  21. I took a closer look at this and realized we'd need to set that config.user variable in the admin theme, and that it'd be better not to have an admin theme dependency for this module. So what I did instead is updated your module to pass along the active tab index in it's JS settings (config.LanguageFieldTabs.activeTab). It determines the active tab based on: if a GET variable is present called "language", containing the ID of a language, it uses that. Otherwise it uses the current user's language. This way you can have it focus on the right language tabs when a user clicks "edit" from the Spanish version of a page, for example. Here is what my edit link looks like on the front end: echo "<a href='{$config->urls->admin}page/edit/?id=$page->id&language=$user->language'>Edit this page</a>"; If there is no "language" GET variable specified, then it just defaults to the current user's language, whatever that may be. The end result is that the tabs always focus on the right language. In testing here so far, it seems to work quite nicely. I just sent over a pull request for this update.
  22. That's not by design, and that's not how it works for me. Just tried it on a page with two image fields "screenshots" and "logos" and it shows images from both. The RTE image/file selection tools don't know anything about fields named "image" or "files", they just look for fields that extend FieldtypeFile.
  23. Looking great Soma. One quick suggestion would be to update your getDatabaseSchema method to have separate indexes on the width, height and depth. Currently, your index would only be used if one queried width and height and depth, or width and height, or just width, as the order matters in a combined index. If someone tried to query height independently of width, an index wouldn't be used. Whereas if width, height and depth each had their own index (either to replace, or in addition to the existing index) then they would all have the potential of having their indexes used in PW queries. This is assuming my understanding of MySQL combined indexes is correct: if you query just depth or height there would be no index to use since it is not the first named field in any combined index.
  24. I'm not sure why it wasn't working in my case, but will try again. Good to know how the capability is provided (collagePlus), I like it so much you have me thinking this should be the default output.
  25. There's no harm in going the multi-tree route. Technically, it's probably the simplest to understand and implement. But it is also more work to maintain as it grows. As things get larger, I think you'd enjoy having the Multi Language Page Names + Multi Language Fields modules handling it for you. So it sounds like you are on the right track. Though if you are literally talking about a tiny site (you mentioned 2 pages?) I'd keep it simpler and just use multi-trees, though I think it's still a good experience regardless of what multi-language setup you use.
×
×
  • Create New...