Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/15/2012 in all areas

  1. @ryan - I did exactly that.. a redirect template, but instead of a field for a url, I used a page input field. Works wonders. Totally happy with this solution, even the redirect is ok IMO. Although easy (like you said) to modify the navigation output to give preference to the page field url instead. I agree wholeheartedly that the navigation in almost all cases should reflect that page tree, and normally that is what happens. This is exactly why I love PW. No joke. I feel like anything is possible and I always end up with an awesome solution that doesn't complicate things.
    2 points
  2. I almost always try to structure sites in a manner is consistent structurally and navigationally. I also think this is one thing that differentiates ProcessWire sites from some other CMSs (like Drupal), where the navigation structure is completely disconnected from the content organization -- it's maddening. So I think it's good to consider structure and navigation in the same process when possible. If you have a huge disconnect between the two, it's good to look at re-evaluating the structure. But I totally understand the need to have a custom menu in one place, or insert a page from a menu in another place, etc. Here's how I do it: When you need to have a navigation link in an existing structure, even though the page isn't in that structure, you can give it a placeholder. Create a field called "redirect_url" of type "URL". Create a template called "redirect" and add your "redirect_url" field to it. Then paste the following in your /site/templates/redirect.php file: <?php $session->redirect($page->redirect_url); Now whenever you need an extra navigation item somewhere in your structure, without the page actually being there, create a placeholder page using the "redirect" template. Put in the URL to the page you want it to go to. When the page is viewed, it'll end up where it's supposed to go. If you want to avoid the 301 redirect, you can also just update your navigation output code to give preference to a redirect_url field when it exists. And it'll use redirect_url when it's populated, and url when it's not: <a href="<?=$page->get('redirect_url|url')?>"><?=$page->title?></a> When you need to create a custom menu that has nothing to do with the site's structure, use a page reference field. For instance, lets say you wanted to create a "footer_links" navigation. You'd create a new multi-page reference field called "footer_links". Choose "Page List Select Multiple" as the Input field for it. Add this field to your homepage template. Edit your homepage and use that field to select the pages, anywhere in your site, that will be in the footer links navigation. Then output them like this: <ul id='footer_links'> <?php foreach($pages->get('/')->footer_links as $item): ?> <li><a href='<?=$item->url?>'><?=$item->title?></a></li> <?php endforeach; ?> </ul> Let me know if I've answered consistently with what you were looking for, or if you are trying to do something else?
    2 points
  3. Turns out Marions idea was right, the "real" original image dimensions were 4272 × 2848 – oh, and by the way, the forum is missing an animated smiley banging his head to a table.
    2 points
  4. I generally try to use as little echo lines as possible. My code will be more like this <ul> <?php foreach($some as $else): ?> <li><?=$else;?></li> <?php endforeach;?> </ul> that way i don't have to worry about indention ...
    2 points
  5. I understand what you are saying. I haven't used anything outside of PHP but i have used a few other cms/f products and none of them i really liked. Until i found PW. In the end it's all about using the right tool for the job, but in my experience PW is the right tool for a whole lot of jobs.
    2 points
  6. Awhile back, I made an Ajax API for querying pages in the admin via the ProcessPageSearch module. It is used by [for example] the PageAutocomplete Inputfield. I thought this capability would be useful on the front-end too, so this module brings it to the front-end as a page in your site that you can put wherever you want to. The way you use it is exactly the same as the one in ProcessPageSearch, but this one is a little more strict, given that it's publicly available on the front-end. By "more strict" I mean that you have to define what you want to allow in terms of input and output in the module's configuration. The web service takes it's query from GET variables in the URL and returns results in JSON format. It installs a page called /service-pages/ in your site, and you are welcome to move that page wherever you want. Here is the official page at modules.processwire.com: http://modules.processwire.com/modules/service-pages/ Once installed, you should view the /service-pages/ page that it installs because it outputs detailed instructions and examples on how to use it in your own projects. But here's a few excerpts from what you'll find on that instructions page: Input The /service-pages/ page can be queried with GET variables in the URL to return JSON-format results. The query string should follow a ProcessWire selector format ([field][operator][value]), but modified a bit for use in a URL query string. Here are a few format examples: Specify a single value: ?field=value Specify multiple fields and values to match: ?field1=value1&field2=value2&field3=value3 Specify multiple fields where at least one must match the value. Note use of "," rather than "|", something we had to settle for to make it work as a URL key: ?field1,field2,field3=value Specify one field with multiple possible values (it's fine to use "|" as a separator here): ?field=value1|value2|value3 Note that unlike regular ProcessWire selectors, multiple field=value sets are split with an ampersand "&" rather than a comma ",". Allowed Values The allowed values for field are set with the module configuration. You may also specify the following modifier keyword=value pairs: sort=[field] (Specify field name to sort results by) debug=1 (Enables debug mode producing human readable output) limit=[n] (Specify the max number of pages to return) start=[n] (Specify the result number to start with) include=hidden (Include pages that are 'hidden') Allowed operators The operator demonstrated by the "=" sign in the examples above may be replaced with any of the following operators in the query string: = Equal to != Not equal to < Less than > Greater than <= Less than or equal to >= Greater than or equal to *= Contains the exact word or phrase ~= Contains all the words %= Contains the exact word or phrase (using slower SQL LIKE) ^= Contains the exact word or phrase at the beginning of the field $= Contains the exact word or phrase at the end of the field As an example, this ProcessWire selector: template=property, body*=luxury, bedrooms>5, bathrooms<=3 ...would be specified as a query string to this web service like this: ?template=property&body*=luxury&bedrooms>5&bathrooms<=3 Allowed templates For security, the search will only be performed on pages using templates that are defined in the module's configuration. Output The returned value is a JSON format string in the following format (populated with example values): { selector: "title*=something, template=basic-page, limit=50", total: 2, limit: 50, start: 0, matches: [ { id: 1002, parent_id: 4525, template: "basic-page", path: "/test/hello/", name: "hello" }, { id: 1005, parent_id: 4525, template: "basic-page", path: "/test/contact/", name: "Contact Us" } ] } Each of the 'matches' values will also include all the fields you have specified to appear with the ServicePages module configuration. If an error in the query prevented it from being performed, a JSON string in this format will be returned: { errors: [ "Error message 1", "Error message 2 (if there was one)", "And so on..." ] } The web service honors user view permissions. As a result, if you are accessing this service from a superuser account, you are likely to get pages that others users may not see. Superusers get an "include=all" automatically, unless you override it with an "include=hidden". Returned field values The following field values will be returned for all matched pages: id (integer) parent_id (integer) template (string) path (string) name (string) Any other fields may be included from the module's configuration screen. Pagination To paginate, simplify add a "page[n]" url segment to the request URL, i.e. /service-pages/page2/?template=basic-page&sort=name
    1 point
  7. I found (after 2-3 Projects using PW) that it's a good technique to use templates in a way I think hasn't been thought of yet really by some. (Although the CMS we use at work for year, works this way.) I'm sure I'm maybe wrong and someone else is already doing something similar. But I wanted to share this for everybody, just to show alternative way of using the brillant system that PW is. Delegate Template approach I tend to do a setup like this: - I create a main.php with the main html markup, no includes. So the whole html structure is there. - I then create page templates in PW without a file associated. I just name them let's say: basic-page, blog-entry, news-entry... but there's no basic-page.php actually. - Then after creating the template I make it use the "main" as alternative under "Advanced" settings tab. So it's using the main.php as the template file. - This allows to use all templates having the same php master template "main.php" - Then I create a folder and call it something like "/site/templates/view/", in which I create the inc files for the different template types. So there would be a basic-page.inc, blog-entry.inc ... - Then in the main.php template file I use following code to delegate what .inc should be included depending on the name of the template the page requested has. Using the TemplateFile functions you can use the render method, and assign variables to give to the inc explicitly, or you could also use just regular php include() technic. <?php /* * template views depending on template name * using TemplateFile method of PW */ // delegate render view template file // all page templates use "main.php" as alternative template file if( $page->template ) { $t = new TemplateFile($config->paths->templates . "view/{$page->template}.inc"); //$t->set("arr1", $somevar); echo $t->render(); } <?php /* * template views depending on template name * using regular php include */ if( $page->template ) { include($config->paths->templates . "view/{$page->template}.inc"); } I chosen this approach mainly because I hate splitting up the "main" template with head.inc and foot.inc etc. although I was also using this quite a lot, I like the delegate approach better. Having only one main.php which contains the complete html structure makes it easier for me to see/control whats going on. Hope this will be useful to someone. Cheers
    1 point
  8. One of my clients specializes in putting on conferences/summits around the world, primarily focused on architecture and sustainable design. I mentioned to them how some users here (starting with Netcarver) had expressed interest in a ProcessWire meetup or conference in the UK. This client does conferences in the UK every year and they are extremely enthusiastic about ProcessWire and interested in helping us to put on a conference by letting us collaborate with their conference and share the same venues and accommodations. This would help us benefit from their expertise in putting on conferences (which they've done for more than a decade), as well as help [significantly] on costs in reserving the venues, food, hotels. I have worked with this client since 1994 (18 years), so have a very high level of trust with them. The conference would be in August 2013 and be 1.5 days in London at a major ad agency, then we'd step on a train for an hour or so and do the rest of the conference in Cambridge at Kings College for another 1.5 days (total 3 days). This would be a small but relatively formal conference with presentations and workshops covering everything ProcessWire, design and web development. We'd cover topics at a higher level than you'd find anywhere else in the world. I don't yet have an idea on costs except to say that we'd find a way to make it accessible to as large of an audience as possible, and it would be completely non profit, food and accommodations (for those that wanted it) included. Yet, it'd still be higher class and more personal than any other webdev conference. This is about a year out, so I'm interested in finding out who'd be interested in this. Please 'like' or reply to this post if you would be interested in attending (or presenting) at this conference.
    1 point
  9. Most likely Apache is running as the same user for everybody on the server, probably with a name like "nobody". So it's not going to be able to write to a directory that is only writable to you (755)... it'll only be able to read from it. If the accounts a truly jailed from one another, and one account can't manipulate the files of another (by way of Apache) then 777 should be no problem. Likewise if it's a dedicated or VPS without untrusted accounts on it, then it should be fine. It sounds like that's the only way it'll run right now, so I would set it to that and then check with the web host what they recommend for Apache-writable directory permissions, and do what they suggest. You might also inquire if you can get an suPHP environment, where Apache/PHP would run as your account--in that case, you would only need rwx to yourself (700) or writable to you and rx to others (755).
    1 point
  10. Where exactly are you calling this? If you're inside a static method, you don't have access to the "$this" object, you can use $page = wire('pages')->get(123);
    1 point
  11. I have created a github repository for it here https://github.com/sommerper/ProcessWireImageEffects
    1 point
  12. Your client might transmit a false mime-type. Can this yield trouble? And he may lie to you - unconscious. Maybe he tries to upload a link rather than the actual image. Just an example. Another idea. The real images are really big - to big. And his mail client is nice enough to scale them down if he he send them to you.
    1 point
  13. I figured as much. I just thought you guys we're using an easier technique because most sources I've seen around are perfectly indented. Thanks! I'm new to processwire, barely 3weeks, and yet I've already used it for two websites. The only thing I love more than how powerful this CMS is, is how helpful and friendly the community is. I'll be sticking around for sure, and try to help whenever I can!
    1 point
  14. SiNNut - you are quite right, it's a totally bogus "Apple and Oranges" comparison. I guess the real comparison is down to this; I've heard about how magical RoR is, I've been using it on the course and you know what - I'm totally underwhelmed, despite the all the hype and all of the resource and community around its development over the past 6-8 years or so. By accident, I stumbled on ProcessWire that has been, from what I understand, largely the results of one person combined with the help of an enthusiastic, yet relatively small community by comparison to that belonging to RoR. When I started to look at PW, I was amazed at how well thought out it is, how well architected it is, how easy to use it is, and how powerful it is. I immediately got that "giddy" feeling when you know you've stumbled onto something amazing. I just didn't get that buzz or excitement about RoR despite having heard for years about how good it is and how it's better since V3.
    1 point
  15. If you make it in Atlanta I'll bring at least 5 people up from Florida — hopefully more by the time it actually happens.
    1 point
  16. Here's a start on creating modules documentation. I still need to write a whole section on hooks, but it's fairly complete in other areas. Please feel free to edit/add to this. http://wiki.processwire.com/index.php/Module_Creation
    1 point
  17. Few things that are "nice to know" when building PW modules: Autoload and non-autoload modules: autoload ones are loaded on every page load. So if you need to hook into core, then you probably need autoload. Non-autoload modules are run only by request: $modules->get("myUberModule")->doSomething() When you need hooks? Well.. common things are "do something when page is saved", "alter the output that is generated", "do something before page is accessed" etc.. Actually there is quite a many hooks and best way to find right hook for you need is to ask for it here. Building modules is pretty similar to working with templates. Nothing "special" there. Few notes though: You cannot directly access the PW API variables like $pages, $session, $input etc.. Those are available at $this->pages or wire('pages'). If you have static method(s) in your modules then you need wire('pages') there - so if you want to play it safe always use that (it works on command line scripts also) Modules can have settings - those are very easy to implement (just look examples from other modules that have settings) Modules are cool. init() is run before page is loaded, so if your autoload module needs to know the current page, that is available at ready() method. Forums is your friend, just ask and someone (probably Soma with his quick editing skills) will surely help.
    1 point
  18. Hello again. I kinda got this working with a few different effects. I had to implement a weird fix so the functions don't get called twice (notice the counter used to check if even or uneven) I just can't figure out why that is. If somebody could help that would be great! home.php <?php /** * Home template * */ include("./head.inc"); foreach($homepage->images as $img) { echo("Original</br>"); $image =$img->size(400, 400); echo "<img id='photo' src='{$image->url}' alt='{$image->description}' width='{$image->width}' height='{$image->height}' /><br/>"; echo("Gotham</br>"); $image =$img->size(400, 400)->fx(FieldtypeImageEffects::GOTHAM, 5, 1); echo "<img id='photo' src='{$image->url}' alt='{$image->description}' width='{$image->width}' height='{$image->height}' /><br/>"; echo("Toaster</br>"); $image = $img->size(400, 400)->fx(FieldtypeImageEffects::TOASTER, 1.2); echo "<img id='photo' src='{$image->url}' alt='{$image->description}' width='{$image->width}' height='{$image->height}' /><br/>"; echo("Nashville</br>"); $image = $img->size(400, 400)->fx(FieldtypeImageEffects::NASHVILLE, 1.2); echo "<img id='photo' src='{$image->url}' alt='{$image->description}' width='{$image->width}' height='{$image->height}' /><br/>"; echo("Custom frame</br>"); $image = $img->size(400, 400)->fx(FieldtypeImageEffects::NASHVILLE, 1.2)->fx(FieldtypeImageEffects::FRAME, "polaroid01.png"); echo "<img id='photo' src='{$image->url}' alt='{$image->description}' width='{$image->width}' height='{$image->height}' /><br/>"; break; } include("./foot.inc"); FieldtypeImageEffects.module <?php class FieldtypeImageEffects extends FieldtypeImage implements Module { const GOTHAM = "fxGotham"; const TOASTER = "fxToaster"; const NASHVILLE = "fxNashville"; const FRAME = "fxFrame"; private $counter = 0; public static function getModuleInfo() { return array ( 'title' => 'Image Effects', 'version' => 001, 'summary' => 'Add effects to images', 'href' => 'http://www.persommer.com', ); } public function init() { $this->addHook('Pageimage::fx', $this, 'fx'); } public function fx(HookEvent $event) { $this->counter++; if ($this->counter % 2) { switch ($event->arguments[0]) { case $this::GOTHAM: $event->return = $this->fxGotham($event); break; case $this::TOASTER: $event->return = $this->fxToaster($event); break; case $this::NASHVILLE: $event->return = $this->fxNashville($event); break; case $this::FRAME: $event->return = $this->fxFrame($event); break; default: $event->return = $event->object; } } else { //echo $this->counter . " is even<br>"; } } private function fxGotham(HookEvent $event) { isset($event->arguments[1]) ? $intColorize = $event->arguments[1] : $intColorize = 20; isset($event->arguments[2]) ? $floatGamma = $event->arguments[2] : $floatGamma = 0.5; $prefix = $this->sanitizeFilename("_" . $event->arguments[0] . $intColorize . $floatGamma); $img = $event->object; $imgBaseNameNew = $this->appendToFileName($img->basename, $prefix); $imgPath = $img->pagefiles->path . $img->basename; $imgPathNew = $img->pagefiles->path . $imgBaseNameNew; $this->execute("convert '$imgPath' -modulate 120,10,100 -fill '#222b6d' -colorize $intColorize -gamma $floatGamma -contrast -contrast '$imgPathNew'"); //!is_file($imgPathNew) ? $this->execute($strExe) : false; $event->object->setFilename($imgBaseNameNew); return $event->object; // $pageimage = clone $event->object; // $pageimage->setFilename($imgBaseNameNew); // $pageimage->setOriginal($event->object); // return $pageimage; } private function fxToaster(HookEvent $event) { isset($event->arguments[1]) ? $floatGamma = $event->arguments[1] : $floatGamma = 1.2; $width = $event->object->width(); $height = $event->object->height(); $prefix = $this->sanitizeFilename("_" . $event->arguments[0] . $floatGamma); $img = $event->object; $imgBaseNameNew = $this->appendToFileName($img->basename, $prefix); $imgPath = $img->pagefiles->path . $img->basename; $imgPathNew = $img->pagefiles->path . $imgBaseNameNew; $this->colortone($imgPath, $imgPathNew, '#330000', 100, 0); $this->execute("convert '$imgPathNew' -modulate 150,80,100 -gamma $floatGamma -contrast -contrast '$imgPathNew'"); $this->vignette($imgPathNew, $imgPathNew, $width, $height, 'none', 'LavenderBlush3'); $this->vignette($imgPathNew, $imgPathNew, $width, $height, '#ff9966', 'none'); //!is_file($imgPathNew) ? $this->execute($strExe) : false; $event->object->setFilename($imgBaseNameNew); return $event->object; } private function fxNashville(HookEvent $event) { isset($event->arguments[1]) ? $floatGamma = $event->arguments[1] : $floatGamma = 1.2; $width = $event->object->width(); $height = $event->object->height(); $prefix = $this->sanitizeFilename("_" . $event->arguments[0] . $floatGamma); $img = $event->object; $imgBaseNameNew = $this->appendToFileName($img->basename, $prefix); $imgPath = $img->pagefiles->path . $img->basename; $imgPathNew = $img->pagefiles->path . $imgBaseNameNew; $this->colortone($imgPath, $imgPathNew, '#222b6d', 100, 0); $this->colortone($imgPath, $imgPathNew, '#f7daae', 100, 1); $this->execute("convert '$imgPathNew' -contrast -modulate 100,150,100 -auto-gamma '$imgPathNew'"); $this->frame($imgPathNew, $imgPathNew, "grunge01.png", $width, $height); //!is_file($imgPathNew) ? $this->execute($strExe) : false; $event->object->setFilename($imgBaseNameNew); return $event->object; } private function fxFrame(HookEvent $event) { isset($event->arguments[1]) ? $frameFile = $event->arguments[1] : $framefile = "grunge01.png"; $width = $event->object->width(); $height = $event->object->height(); $path_parts = pathinfo($frameFile); $prefix = $this->sanitizeFilename("_" . $path_parts['filename']); $img = $event->object; $imgBaseNameNew = $this->appendToFileName($img->basename, $prefix); $imgPath = $img->pagefiles->path . $img->basename; $imgPathNew = $img->pagefiles->path . $imgBaseNameNew; $this->frame($imgPath, $imgPathNew, $frameFile, $width, $height); //!is_file($imgPathNew) ? $this->execute($strExe) : false; $event->object->setFilename($imgBaseNameNew); return $event->object; } private function execute($command) { // echo("COMMAND INPUT: " . $command . "<br>"); $out = array(); putenv("PATH=" . $_ENV["PATH"] . ":/opt/local/bin"); exec($command . " 2>&1", $out); // echo("COMMAND OUTPUT: " . print_r($out, true) . "<br>"); } private function appendToFileName($filename, $prefix) { if ($prefix != "") { $path_parts = pathinfo($filename); return $path_parts['filename'] . $prefix . "." . $path_parts['extension']; } return "errorprefix-" . $filename; } private function sanitizeFilename($strFilename) { $strFilename = str_replace(".", "", $strFilename); return $strFilename; } public function colortone($input, $inputNew, $color, $level, $type = 0) { $args[0] = $level; $args[1] = 100 - $level; $negate = $type == 0 ? '-negate' : ''; $strColortone = "convert '$input' \( -clone 0 -fill '$color' -colorize 100% \) \( -clone 0 -colorspace gray $negate \) -compose blend -define compose:args=$args[0],$args[1] -composite '$inputNew'"; $this->execute($strColortone); } public function border($input, $color = 'black', $width = 20) { $this->execute("convert $input -bordercolor $color -border " . $width . "x" . $width . " $input"); } public function frame($input, $inputNew, $frame, $width, $height) { $strFramePath = $_SERVER['DOCUMENT_ROOT'] . "/site/modules/frames/" . $frame; //echo ("DOC LOCATION: " . $strFramePath . "<br>"); $strExe = "convert '$input' \( '$strFramePath' -resize {$width}x{$height}! -unsharp 1.5×1.0+1.5+0.02 \) -flatten '$inputNew'"; //echo ("EXE: " . $strExe . "<br>"); $this->execute($strExe); } public function vignette($input, $inputNew, $width, $height, $color_1 = 'none', $color_2 = 'black', $crop_factor = 1.5) { $crop_x = floor($width * $crop_factor); $crop_y = floor($height * $crop_factor); $strVignette = "convert \( '$input' \) \( -size {$crop_x}x{$crop_y} radial-gradient:$color_1-$color_2 -gravity center -crop {$width}x{$height}+0+0 +repage \) -compose multiply -flatten '$inputNew'"; $this->execute($strVignette); } } Outputs the attached image
    1 point
  19. And since today here: http://modules.processwire.com/modules/process-page-delete/
    1 point
  20. especially when someone answers their own question
    1 point
  21. 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.
    1 point
×
×
  • Create New...