-
Posts
17,241 -
Joined
-
Days Won
1,704
Everything posted by ryan
-
The typing of "images" in a <p> was just an example of using a little template file code to automate some specific runtime output. It's not a standard or even a recommendation, just a little code snippet I found handy in a couple cases. Unless I've misunderstood, now you are asking for exactly what the built-in functionality does– Click on the photo icon in TinyMCE and add a photo. If you then want to link it to something, then click on the photo to highlight it and then click on the link icon to select what you want it to link to.
-
Thanks for all of your feedback on these. Glad that you find them to be pretty good. I know Jim spent a lot of time on them. But I don't think he'll ever get back to them because I think they are keeping him super busy at his new job. Since it sounds like they are going in the right direction, we'll keep updating and adding to these. If anyone is interested in working on them just let me know. One of the main things about these is that they were written a year ago, back when PW was brand new and before version 2.1. The other thing is that you'll see some of the Quick Start tutorials in there are just notes he had made to himself– some aren't finished and some aren't started. So one of the things we need to do is determine if the unfinished ones should be deleted or finished. Thanks, that would be great if you have time to take a look. If you find anything that you don't think is right, feel free to change it too. Thanks, Ryan
-
I hadn't really considered this particular Fieldtype as one that would be used for searching, so that's something we may need to upgrade in FieldtypeModule. However, I think that this should work right now: <?php $id = wire('modules')->getModuleID('SettingItem'); $this->pages->get("template=admin, process=$id, name=completed");
-
I'd forgotten those tutorials were there. The only way to get to them is through the search engine (I think). These were written by my brother-in-law back when PW 2.0 was new (nearly a year ago). He never was able to finish them because he got a new job that takes all his time. These tutorials may not be totally applicable anymore (I haven't read them all yet). But I'd be interested to hear if you guys think they are helpful and if we should update and finish them. Now that they've turned up again, I'm going to read through them in more detail here.
-
Here's how to do it: $page->addStatus(Page::statusUnpublished); Note that $page->status is a bitmask, so it can contain several different statuses at once (for instance, hidden and unpublished). It can be set directly. But because bitwise arithmetic isn't always fresh on my mind, I think it's safer and easier to use $page->addStatus() and $page->removeStatus() for dealing with it.
-
This was actually in early versions of 2.1 as the page-add permission (and it's probably still there just commented out). I took it out because I was worried about providing too many options and resulting confusion with so much crossover between that and the family settings. I like having lots of choices, but access control is one area where I think it's better to just have one way of achieving something. Though I do think we could add page-add permission back as an option, but something we'd probably want to do with an optional module. I understand what you mean. The action you described is also the way family options are supposed to be used. Set things up where you need them, an then lock it down the way you want it. It's meant to be something to direct the flow after you've set the structure and determined who can edit, not at the same time. If everything is working and you are happy then I wouldn't suggest changing it. There's nothing inherently good or bad about having lots of templates–it's generally adds more flexibility, but with the tradeoff of being more to manage. But if you want me to take a look and suggest ways you can do it with fewer templates, I'll be glad to. Though you may be right that you have exactly as many templates as you need too– I'm not familiar with the site or scope of it so can't speak to it.
-
Thanks Pete, this looks great.
-
I agree with all this. Here are the curent module naming conventions (first word in module name): Export - any module that provides site data export capabilities, especially where there may be a related Import module. Fieldtype - any module that extends the 'Fieldtype' class. Represents a data type used by ProcessWire fields. Form - any module that deals with creating/processing web forms (some crossover potential with Markup). Inputfield - any module that extends the 'Inputfield' class. Represents an HTML input widget used to collect data in the admin. Import - any module that imports data to create new data in a PW site. Jquery - any module that adds something related to jQuery/Javascript. Language - any module that provides support for other languages Process - any module that extends the 'Process' class. Typically attached to a page for handling admin actions. If it's related to another Process module (core or 3rd party) it's name should start with that module, i.e. ProcessPageEditLink is related to ProcessPageEdit. Markup - any module designed for creating or parsing markup Page - any module designed to add capabilities to PW's Page class. Textformatter - any module that extends the 'Textformatter' class, for runtime output formatting of text fields. Some of the naming conventions are based on the root class that they extend, though not all. New additions to this list likely won't be based on extending some built-in class, since there aren't any others. Though I would suggest that when a module doesn't fit in the above, it should start with the class name of the core class or module it is hooking into (not unlike the 'Page' one above). So if you are adding hooks to the Pages class, then start your module with 'Pages'. Likewise if you are adding hooks to the Session class, then start your module with 'Session'. Beyond this, the naming conventions are open ended. I guess the first thing we have to determine is: what are the major classes of modules that aren't covered above? I can't think of any at the moment, but I know they are there.
-
We'll let this one marinate for awhile and see if new posts separate from this one turn up where people think it's a bug. It'll be on probation.
-
I like MarkItUp. Actually I used that in PW1 as an option in addition to TinyMCE. Would be good to bring back at some point.
-
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
Thanks for the update Jasper. Looks like we've got a double encoding issue there–thanks for pointing this out, I'll implement a fix. For security, I have everything coming out of the translator as pre-encoded – prevents those JSON files from ever being used for anything malicious. But there are some instances (like that breadcrumb) that may be doing their own encoding (resulting in double encoding). Please let me know if you come across any others. Thanks, Ryan -
Okay glad you guys like it. But if anyone thinks it looks like a mistake, then it may need more tweaks. And as always please be honest.
-
Soma, just wanted to let you know I haven't forgotten this, but wanted to reply when I had time to put some more thought into it (early next week). If you want to send over the access that'd be great too.
-
I agree, we'll get there. This needs to accompany the larger module documentation, something that I'm hoping to get in place shortly after the 2.2 release.
-
A different way of using templates / delegate approach
ryan replied to Soma's topic in API & Templates
I agree, though also think it's a delicate balance. I'd like people to perceive ProcessWire as something like Google (in terms of simplicity) – they can start using it without really having to know anything. They can discover the depth of it as their needs grow. If the depth is out in front, they might be overwhelmed. So I like to keep lots of surface simplicity and let PW grow with them. Most of what you use PHP for in a template is no different than how you would use some other template engine, except in syntax. So something like: <p>$somevar</p> is probably not a good example because there is no logic there, it's just pure output generation. You have to connect your variable to the markup at some point, and it doesn't get any simpler than that. I do think the point is valid when you get down into code that isn't geared towards output generation. But the nature of PW's API is that all the data is put at your fingertips so your template code can focus on output generation. The logic (or lack of it) that one uses in PHP at this level isn't really any different than that provided by something like Smarty, EE or another template engine. What is different is that PW puts all of the site's data at close reach, rather than some specific subset of it. That kind of resembles working in Javascript with the DOM. As you start working at a larger scale, using some discipline in how you do things can help you in the long run. I'm not talking so much about whether something is in a <p> or <li> tag, but about stuff that would create major obstacles if you wanted to completely re-skin your site tomorrow. An example of something that does go beyond output generation a little is a search engine. This is one of the reasons why I like the approaches we've been talking about, because it does a good job of isolating logic where it matters. This particular example doesn't have any real logic of the sort I'm thinking of, but pretend for a moment that it was a much bigger/more complex search engine: search.php <?php $q = $sanitizer->selectorValue($input->post->q); $results = $pages->find("title|body|sidebar*=$q"); $page->body .= $results->render(); include("./main.php"); Or using something like your guys method, where a separate view file generates output separately: search.php <?php $q = $sanitizer->selectorValue($input->post->q); $page->searchResults = $pages->find("title|body|sidebar*=$q"); /* then the output file /includes/search.inc knows to output results from $page->searchResults */ include("./main.php"); Another thing I've found that works well is to put reusable output generation in modules and attach it to PageArrays, not unlike $results->render(). For example, on those villa sites, I have a PageArray::renderVillas hook that can be called anywhere in the site and it always renders villas the same way, provides a sort select at the top, and knows to handle pagination. Likewise, I added a Pages::villas() hook that only finds villas and automatically plugins in the proper limit=n for consistent site-wide pagination. So if I needed to re-skin the site tomorrow, I could update all the site's villa lists in one shot (and there are hundreds of them). As time goes on, I think it'll be good for us to document best practices for large scale use. Like with PHP itself, I'm glad PW doesn't force us into one way of doing things. But I think it'll be helpful to lots of others if we outline what we've found helps to maximize scalability, longevity, etc. At the same time, when it comes to teaching people how to use ProcessWire with examples, I think some of these best practices can confuse the message. I wouldn't suggest that someone learning ProcessWire should use it in pure MVC mode until that is appropriate for their scale and need. It's only when you go bigger and more complex that your template code starts to become something more than a 'view', and it's at that point where you need to start considering the long term. I think this is only worthwhile if you are dealing with some other group of people that is creating the output files, and that group refuses to get anywhere near PHP. Ultimately they just need to be told that there's no difference between <?=$somevar?> and {{$somevar}} except for a lot of unnecessary overhead for the {{$somevar}} version. More here: http://processwire.com/api/why-php-syntax/ It would be easy possible within PW to create markup-generating type of modules. Not sure If that should be done, as It's a little against PW's philosophie. Markup generating modules are fine I think, but I just don't want PW's core to generate any markup. I figure it should always be markup neutral. But markup generating modules can be very handy. Though my preference is for markup generating modules to provide options for customizing that markup. Me too. Though when providing these as something beyond a basic example, I think it invites an audience that is interested in turn-key solutions and not web development. Such things require good support. Thats why I think there is a good fit for paid solutions in this (like Maruchan brought up). -
How to set template or parent restrictions through API for page-field?
ryan replied to apeisa's topic in API & Templates
Here are the fields you can set with a Page field: <?php $f = $fields->get("some_page_field"); // InputfieldPage settings $f->parent_id = 123; // ID of allowed parent page $f->template_id = 4; // ID of allowed template $f->findPagesCode = 'return $page->parent->children();'; // alternate code to use for included pages $f->labelFieldName = 'title'; // name of field to use as label (default is title) $f->inputfield = 'InputfieldSelect'; // class name of inputfield you want to delegate selection to // FieldtypePage settings $f->derefAsPage = FieldtypePage::derefAsPageArray; // Multiple pages (PageArray) $f->derefAsPage = FieldtypePage::derefAsPageOrFalse; // Single page (Page) or boolean false when none selected $f->derefAsPage = FieldtypePage::derefAsPageOrNullPage; // Single page (Page) or empty page (NullPage) when non selected The Inputfield settings only affect what is displayed in the admin (i.e. for locating what pages it should display as selectable). -
Progress on ProcessWire 2.2 and overview of multi-language support
ryan replied to ryan's topic in Multi-Language Support
Thanks for the update Nico. -
How to create quick variables like $users, $roles etc..
ryan replied to apeisa's topic in API & Templates
To use PagesType, you have to specify a template and parent_id to the constructor. You actually don't need to extend PagesType unless you want to. I think you could achieve what you are wanting to do just like this: <?php $template = $templates->get('order'); $parent = $pages->get('/orders/'); $orders = new PagesType($template, parent->id); -
Thanks for this! I think that twitterfeed.com actually looks like what they were wanting (at least that's what it appears on the surface). We may have to give this a try. Thanks again.
-
The little overlap there is intentional, and I put it on low opacity so we could get some interesting blending/overlapping when the browser window size located it there. If you roll over it it'll go full opacity again. I thought you guys would like it :-\ I suppose I could take it higher opacity so that the overlapping is barely noticeable, or full opacity for no visible overlap. But since it's the only button over there I thought it was an opportunity to do something a little more interesting.
-
I have a question from a client that I didn't know the answer to, and was wondering if anyone here does. Lets say you have an RSS feed in ProcessWire outputting your news stories. Is there a way to setup Twitter and/or Facebook (even if 3rd party tool required) to automatically send out a new tweet/post when something is added to the RSS feed? I would think there should be, but just didn't know. I do know you could do it with their APIs, but didn't know if one could connect an RSS feed to their Twitter/Facebook feed.
-
A different way of using templates / delegate approach
ryan replied to Soma's topic in API & Templates
I like that idea, being able to swap in a larger chunk of markup like that. I need to give this a try. I really like this thread, you guys have some great ideas. -
Yes Dictator was a bad name. But it had good intentions. It was the name of one of Thomas Edison's inventions for some machine that assisted with outputting content. It was supposed to be that kind of Dictator, not the kind that tells others what to do or an evil ruler or anything like that.
-
A different way of using templates / delegate approach
ryan replied to Soma's topic in API & Templates
Thanks for posting Soma, this is an interesting approach and not one I've seen before, but it looks great. The underlying concept and result is similar to the approach I usually use. Since you posted a good description, I'll try to do the same for mine. The only reason you see head/foot files in the default PW profile is because it seems to be simpler for new users to grasp. But I almost never use that approach in my own sites. Like your system, I have a main.php file which is my main markup file. But unlike your system, main.php is included from all the other template files (rather than main.php including them). The other template files focus on populating the key content areas of the site, specific to the needs of the template. Examples of key content areas might include "main" (for center column/bodycopy) and "side" (for sidebar/related info), though often includes several other identified areas. But I'll keep it simple in this case. Here's how it works: basic-page.php <?php $outMain = "<h2>{$page->subtitle}</h2>" . $page->body; if($page->numChildren) $outMain .= $page->children->render(); // list the children $outSide = $page->sidebar; include("./main.php"); main.php <html> <head> <title><?php echo $page->title; ?></title> </head> <body> <h1><?php echo $page->title; ?></h1> <div id='main'><?php echo $outMain; ?></div> <div id='side'><?php echo $outSide; ?></div> </body> </html> The benefit of this approach is that basic-page.php can setup whatever it wants in the key content areas ($main or $side) whether simple like in this example, or something much more complex. I actually prefer for the variables representing the key content areas to be optional. In the scenario above, $outMain and $outSide would have to be defined by every template or they would end up as uninitialized variables in main.php. As a result, I actually use $page as an anonymous placeholder for these variables (making sure they don't conflict with any existing field names) and then let main.php assign defaults if the calling template didn't specify one of them. For example: basic-page.php <?php $page->outMain = "<h2>{$page->subtitle}</h2>" . $page->body; if($page->numChildren) $page->outMain .= $page->children->render(); // list the children // note: no $outSide specified include("./main.php"); main.php <?php // setup defaults when none specified if(empty($page->outMain)) $page->outMain = $page->body; if(empty($page->outSide)) $page->outSide = $page->sidebar; ?> <html> <head> <title><?php echo $page->title; ?></title> </head> <body> <h1><?php echo $page->title; ?></h1> <div id='main'><?php echo $page->outMain; ?></div> <div id='side'><?php echo $page->outSide; ?></div> </body> </html> Final thing to point out here is that main.php is the only template actually outputting anything. Because basic-page.php (or any other template) is determining what's going to go in that output before it is actually sent, your template has the opportunity to modify stuff that you might not be able to with other methods. For instance, the <title> tag, what scripts and stylesheets are loaded, etc. Here's the example above carried further to demonstrate it: basic-page.php <?php // make a custom <title> tag $page->browserTitle = $page->rootParent->title . ": " . $page->title; $page->outMain = "<h2>{$page->subtitle}</h2>" . $page->body; if(count($page->images)) { // display a clickable lightbox gallery if this page has images on it $config->scripts->add($config->urls->templates . "scripts/lightbox.js"); $config->styles->add($config->urls->templates . "styles/gallery.css"); $page->outMain .= "<ul id='gallery'>"; foreach($page->images as $i) { $t = $i->size(100,100); $page->outMain .= "<li><a href='{$i->url}'><img src='{$t->url}' alt='{$t->description}' /></a></li>"; } $page->outMain .= "</ul>"; // add a note to $page->title to say how many photos are in the gallery $page->title .= " (with " . count($page->images) . " photos!)"; } if($page->numChildren) $page->outMain .= $page->children->render(); // list the children include("./main.php"); main.php <?php // if current template has it's own custom CSS file, then include it $file = "styles/{$page->template}.css"; if(is_file($config->paths->templates . $file)) $config->styles->add($config->urls->templates . $file); // if current template has it's own custom JS file, then include it $file = "scripts/{$page->template}.js"; if(is_file($config->paths->templates . $file)) $config->scripts->add($config->urls->templates . $file); ?> <html> <head> <title><?php echo $page->get('browserTitle|title'); // use browserTitle if there, otherwise title ?></title> <?php foreach($config->styles as $url) echo "<link rel='stylesheet' type='text/css' href='$url' />"; foreach($config->scripts as $url) echo "<script type='text/javascript' src='$url'></script>"; ?> </head> <body> <h1><?php echo $page->title; ?></h1> <div id='main'><?php echo $page->get('outMain|body'); // use outMain if there, or body otherwise ?></div> <div id='side'><?php echo $page->get('outSide|sidebar'); // use outSide if there, or sidebar otherwise ?></div> </body> </html> More than half the time, I'll actually just re-use page variables like $page->body and $page->sidebar rather than $page->outMain and $page->outSide. That way there's no need to consider defaults, since $page->body and $page->sidebar untouched technically are defaults. <?php $page->body = "<h2>{$page->subtitle}</h2>" . $page->body . $page->children->render(); But technically you've got a little more flexibility using your own self-assign anonymous variables like outMain and outSide, so figured I'd use that in the examples above. outMain and outSide are just example names I came up with for this example and you could of course name them whatever you want.- 83 replies
-
- 22
-
-
You'd have to use a little bit different approach because a session has to be active before we know who the user is. The session hasn't yet started when the config file is being loaded. So you'd detect who the user is somewhere else (like in your main site template) and then set a cookie before any output starts: setcookie('guest', $user->isGuest() ? 1 : 0); Then detect the cookie in your config.php: $config->sessionExpireSeconds = empty($_COOKIE['guest']) ? 86400 : 23200; You wouldn't want to use this method for anything security related, but session time is really not a security concern I don't think.