Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/01/2013 in all areas

  1. Module for admin and front-end resizing and rasterizing of vector SVG images Requirements IMPORTANT: This module requires Imagemagick and the pecl imagick extension. For anything but simple SVGs, you must make sure imagemagick was compiled with a relatively recent version of rsvg (I know that 2.32.1 works well and presumably anything more recent should also be fine). If you don't manage your own server and the results are not good, check with your host. If everything is set up correctly, the rendered PNGs will be "perfect" representations of the SVGs. See this post below for just how much of a difference rsvg can make. How to use You must add SVG as an allowed file type for a multiple images field. Check the module configuration for a variety of settings for both PNG and JPG output options. In particular be aware of the Rasterized Images Field selector. If you choose "None" only the SVG will be stored in the images field. You can still access rasterized versions via the rasterize() method - see below for details. NB: You need to be running a recent dev version (or 2.4 stable once available) of Processwire that supports field dependencies for the configuration settings to work as expected. Once the module configuration settings are completed: Upload an SVG image and the module will create a rasterized version. You need to save the page to see the rasterized version which can then be accessed via the API like any other image. The module also adds a new method: rasterize() which can be called from your templates like: $image->rasterize(200,0)->url This method optionally resizes the vector version of the image and then rasterizes it so you can scale it infinitely and there will be no loss of quality. Make sure you point it to the svg version in your images field. Modules Directory: http://modules.processwire.com/modules/image-rasterizer/ Github: https://github.com/adrianbj/ImageRasterizer
    4 points
  2. if ($page->user->has($user)) { // Do stuff } Not tested, but something like this would work since the "user" fields returns a array which you can check all kinds of thing in. See the cheatsheet for more info.
    4 points
  3. I just (like 5 mins ago) implemented "Most Viewed Pages" widget for a client. I used Wanzes excellent ProcessGoogleAnalytics module and it was easy enough pull data when it was first setup. It might be that this is not a fit for your project Martijn (if you need the data for selectors for example), but this is how I did it: $pga = wire('modules')->get("ProcessGoogleAnalytics"); $ga = new GoogleAnalyticsAPI(); $ga->auth->setClientId($pga->clientId); $ga->auth->setClientSecret($pga->clientSecret); $ga->auth->setRedirectUri($pga->page->httpUrl); $ga->setAccessToken($pga->accessToken); $ga->setAccountId($pga->accountId); $defaults = array( 'start-date' => date('Y-m-d', strtotime('-1 month')), 'end-date' => date('Y-m-d'), ); $ga->setDefaultQueryParams($defaults); $params = array( 'metrics' => 'ga:pageviews', 'dimensions' => 'ga:pagePath', 'sort' => '-ga:pageviews', 'max-results' => 11, ); $visits = $ga->query($params); $out = "<h2>Most read articles</h2><ul>"; foreach($visits['rows'] as $row) { if ($row[0] == "/") continue; // Skip the homepage, should be on top 10 always, if not, then 11 articles is shown $p = $this->pages->get($row[0]); if ( ! $p->id ) continue; // For some reason page is not found anymore... $out .= "<li><a href='$p->url'>$p->title</a></li>"; } $out .= "</ul>";
    4 points
  4. Hey ho, I wrote a new module: ProcessShortcodes. It brings Wordpress like shortcodes to Processwire. A quick example: <?php $shortcode = $modules->get('MarkupShortcodes'); $shortcode->add('login', function($atts){ return '<form><h3>'.$atts['content'].'</h3><label>Enter password for "'.$atts['name'].'":</label> <input type="pass"></form>'; }); $content = 'Lorem ipsum dolor [login name="user"]Login[/login]'; echo $shortcode->render($content); ?> You can: add a shortcode: $shortcode->add('login', function($atts){ return '<form><h3>'.$atts['content'].'</h3><label>Enter password for "'.$atts['name'].'":</label> <input type="pass"></form>'; }); remove a shortcode: $shortcode->remove('login'); remove all shortcodes: $shortcode->remove_all(); and use them: $shortcode->render('Lorem [ipsum /] hello. [dolor name="nico" /]. Third possibility: [abc def="hij"]a text[/abc]. '); As seen above there are three different possible syntaxes: 1.: [shortcode] or [shortcode /] 2.: [shortcode key="value" /] or [shortcode key="value"] or [shortcode key="value" second="bla" /] 3.: [shortcode]lorem ipsum[/shortcode] or [shortcode key="value"]lorem ipsum[/shortcode] or [shortcode key="value" second="bla"]lorem ipsum[/shortcode] You can download it here: https://github.com/NicoKnoll/MarkupShortcodes I will add it to the module section as soon as possible.
    1 point
  5. A quick tutorial how to create file downloads using pages You will be able to create a new page using template "PDF" (or any you setup), upload a pdf file. You then can select this page using page fields, or links in Wysiwyg. The url will be to the page and NOT the file itself. This will allow to keep a readable permanent unique url (as you define it), unlike /site/assets/files/1239/download-1.pdf, and you'll be able to update/replace the uploaded file without worring about its filename. Further more the file will also have an id, the one of the page where it lives. Clicking those links will download or open the file (when target="_blank") like it would be a real file on server with a path like /downloads/project/yourfile.pdf. You'll be also able to use the "view" action directly in the page list tree to view the file. Further more you'll be able to esaily track downloads simply by adding a counter integer field to the template and increase it every time the page is viewed. Since the file is basicly a page. This all works very well and requires only minimal setup, no modules and best of it it works in the same way for multi-language fields: Just create the language alternative fields like "pdf, pdf_de, pdf_es" and it will work without modifying any code! Still with me? ok PW setup Download folder: Create a template "folder" or "download-folder" with only a title needed. Create pages in the root like /downloads/project/ using this template. Setup the template for the pdf files 1. Create a new template in PW. Name it pdf 2. Goto template -> URLs tab and set the URL end with slash to no. (So we can have /path/myfile.pdf as the URL) 3. Create a new custom file field, name it pdf. Set its maximal count to 1 under -> Details tab. 4. Add the pdf field created to the pdf template. Easy. 5. Create a new "pdf" page using the pdf template under a download folder you created earlier. 6. Give it the title and in the name field add ".pdf" to the end (could also leave as is) Template PHP file for the pdf files 1. Create the template file pdf.php in your /site/templates folder 2. add the following code: <?php // pdf.php if($page->pdf){ wireSendFile($page->pdf->filename); } Done. To see the options you have with PW's wireSendFile() you can also overwrite defaults <?php // pdf.php if($page->pdf){ $options = array( // boolean: halt program execution after file send 'exit' => true, // boolean|null: whether file should force download (null=let content-type header decide) 'forceDownload' => false, // string: filename you want the download to show on the user's computer, or blank to use existing. 'downloadFilename' => '', ); wireSendFile($page->pdf->filename, $options); } Simple and powerful isn't it? Try it out. Some thoughts advanced Create as many file types as you like. It might also be possible to use one "filedownload" template that isn't restricted to one field type but evaluate it when being output using $page->file->ext, or save the file extension to the page name after uploading using a hook. One last thing. You can add other meta fields or preview images to the template and use those to create lists or detail pages. It's all open to goodness. Again all without "coding" and third-party modules. Further more you can use the excellent TemplateDecorator to add icons per template and have a nice pdf icon for those pages. This as a base one could also easily create a simple admin page for mass uploading files in a simple manner, and create the pages for the files automaticly. ImagesManager work in the same way. Cheers
    1 point
  6. Chrome Php Logger Module to log useful details directly in your Chrome JS console. You can inspect most as objects and see infos or values. To enable logging with this module you have to enable debug modue in config.php. If debug is set to false in config.php, it will not output any log. Important: It is not recommended to enable it on live stage, as it reveal infos you might not want everybody to see, although it's not obvious as it requires the ChromePhp Extension installed and enabled. - render time - memory consumption - cpu usage - current user infos - current user roles - current user permissions - current page with all its fields and their value and field settings - page cache/loaded on request count - fuel - modules loaded - Server vars etc. - Cookies - Requests - mySQL query log When installed you can also use ChromePhp static methods to output your own data in all your templates or modules: ChromePhp::log($page->somefield); Note: This module requires the ChromePhp Extension installed to see the log in the Javascript console. More infos can be found on http://chromephp.com Download: Modules Directory: http://modules.processwire.com/modules/chrome-php-logger/ Github: https://github.com/s...ChromePhpLogger
    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. I find myself browsing through the system to reach certain pages, settings or modules over and over again. It would save a lot of time if I could bookmark these pages with like a star button on top (in edit mode) or something on a system level or/and user level. Then perhaps in an extra item in the top navigation called bookmarks, would list them all. System level because other users could use them too. Any thoughts on this? Perhaps even some suggestions how to implement that?
    1 point
  9. Started a new module for creating <tables> from repeater fields. Feel free to grab it from github, do with it what you want. It only works for simple text based fields inside a repeater. To use it: $table = $modules->get("RepeaterTable"); // initialize $table->thead = true; // (bool) true/false, default = true, will render <th> $table->indent = 3; // (mixed) false/int, where int is the level of indentation, default: false $table = $table->render($page->repeater); // repeaterfield called repeater <!-- output --> <table class="table-repeater"> <thead> <tr> <th class="col-1">Fieldlabel field 1</th> <th class="col-2">Fieldlabel field 2</th> <th class="col-3">Fieldlabel field 3</th> </tr> </thead> <tbody> <tr class="row-1"> <td class="col-1">data for field 1, first repeater item</td> <td class="col-2">data for field 2, first repeater item</td> <td class="col-3">data for field 3, first repeater item</td> </tr> <tr class="row-2"> <td class="col-1">data for field 1, second repeater item</td> <td class="col-2">data for field 2, second repeater item</td> <td class="col-3">data for field 3, second repeater item</td> </tr> </tbody> </table> For the HTML purist, I have added source code indentation where you can set how many tabs you wish to append before each element. Please let me know if I should add this to the modules directory ? Does someone have a good name for this ?
    1 point
  10. Hi, im trying to play with the repeaters; i read the excellent tutorial on this page and made some groups for a project but i have a few questions. Is possible to every item for a repeater (item) be collapsed in the panel admin? Is possible change the title for the row, to know his content without need to click then? Regards.
    1 point
  11. I had a click while reading this post http://processwire.com/talk/topic/4642-keeping-a-page-in-a-fixed-position-last-in-the-sorting-order/ and quickly implemented something I was thinking about for some time already. I added a new functionality on the DEV version. Now the module allows to easily create a "settings" kind of page. Putting it simply, you can create a tab in the admin that shows the "edit" page of that same page. See it for yourself https://github.com/ocorreiododiogo/pw-admin-custom-pages/tree/dev edit: for those interested on how it works, don't look on the module file, look on the admin.php file.
    1 point
  12. I'm seeing certain similarities with another thread, http://processwire.com/talk/topic/3530-most-selector-operators-throwing-errors/. Even the exception matches that thread perfectly. There's no "*=" or "%=" with page type field (just like that exception says.) It's not a bug or missing feature either, it's just that there's no need for such an operator. With page type fields "=" simply checks if page field value contains a value, not if it's equal to it What Antti pointed out above seems to be exactly what you're after; per your description you've got products with a field "categories" and pages with one category selected and you want to find any products that include that category in their "categories" fields. In this case this should do the trick: $pages->find("categories={$page->category}"); I'd even go as far as say that if it doesn't seem to work, the issue is probably something entirely different. Just to make sure, in your original post you mentioned field "categories" for products and your selector was "category=...", is it possible that something similar (ie. misspelled field name) is the actual issue here?
    1 point
  13. @Raymond: 1) As a first workaround you may install PiM too, and set $config->imageManipulatorOptions sharpening to none. That way you can leave $config->imageSizerOptions as is, while all CropImages should be handled by PiM (the automaticly created) and with the manual created you need to select none in the dropdown-list. 2) can you send me or upload an example of this black lines/dots noises? There is a BUG in GD-Lib with Alpha-Transparency in PNG. It isn't recognized by some functions.
    1 point
  14. You can also use Soma's http://modules.processwire.com/modules/chrome-php-logger/ to have all the info in more organized way
    1 point
  15. I am little confused what you are trying to achieve and why it doesn't work. I think part of the confusion is that I don't understand how you have setup your products and categories and how they relate each others. In most common "multicategory" setup product has field called "category" that allows one or more categories. Then the selector is simple as this: $pages->find("category=$categories");
    1 point
  16. unfortunately this only works the other way round than what i need... the field (left side of the operator) has multiple values, while the value (right side of the operator) has only one. what i need to accomplish is finding out if the value on the right side matches one of the field values. if i could just flip the operands... i can't think of an easy way to do this, but maybe someone smarter than me can...
    1 point
  17. You could do category.name=cat1name|cat2name|cat3name Basically the pipe character --> | <-- means OR, which should work for your case. The above is for the page name field, but you could just as easily do category=1027|1038|1057 if you want to match against the page ID
    1 point
  18. Well, I do love highcharts
    1 point
  19. tnx apeisa, interresting ! I gonna marinate this a little. As my needs are indeed a little different. Think I gonna use abuse WebPageServices module cause I want to use it for other items to. Thank you guys for resetting my brain.
    1 point
  20. Creating a template php file in your file system won't automatically create a template in PW. You still need to go to Setup > Templates and add the new template. Also, I am not sure why you are creating a separate brands-head.inc file. All you need to do is add a conditional statement in your head.inc file. Something like: if($page->template != "brands-basic-page"){ //echo the sidebar } Let us know if that helps you sort things out.
    1 point
  21. Manol, You can definitely use one file for the structure. Ryan has a pretty good explanation of the approach here: http://processwire.com/talk/topic/740-a-different-way-of-using-templates-delegate-approach/?p=6174
    1 point
  22. I'm confused - this would surely just echo the URL of that page: echo $header_page->url; ?? To render it you would want this instead: $header_page->render(); So in your other script, you could do this: // Include ProcessWire require("../index.php"); // Get header $header_page = wire()->pages->get("/external_head/"); $footer_page = wire()->pages->get("/external_foot/"); echo $header_page->render(); //.... the rest of your other script goes here echo $footer_page->render(); That should work I think, unless I've misunderstood what you're asking for. It also assumes that there will be no conflicts between variables in ProcessWire and your other script, but you would know if that's the case soon enough when it throws you errors I must admit, I do like the concept. I know of an intranet script I've worked on in the past where I tried to make ProcessWire work inside that script's header and footer for old pages, and new pages had the header and footer and the pages themselves in ProcessWire, but this would have been a better idea in terms of wrapping a consistent header and footer around both the old and the new pages until they're all ported over to ProcessWire.
    1 point
  23. Do you guys think it makes sense to bring LanguageFieldTabs into the core? So far I haven't come across a multi-language site install where I wouldn't want it, so starting to wish it was just there by default.
    1 point
  24. Soma, reading through php.net, it sounds like versions of PHP prior to 5.3.8 had incorrect behavior for is_subclass_of(). In those versions, the only straightforward way to determine it is I guess to use Reflection. I've added a PHP version check which falls back to Reflection in older versions of PHP, but don't have a PHP version to test it out with. Do you want to try replacing your /wire/modules/Inputfield/InputfieldPage/InputfieldPage.module with the attached and let me know if this resolves the issue? InputfieldPage.module
    1 point
  25. Actually found the part of code that misses the imagealphablending and imagesavealpha. Submitted a pull request
    1 point
  26. Thanks to Ryan, in the dev-branch we now have Pageimage::isVariation() hookable. I have added a hook to the init() method of PiM $this->addHook('Pageimage::isVariation', $this, 'isVariationWithPim'); and with this method all valid pimVariations of a Pageimage get collected / deleted together with the other variations of the original image: public function isVariationWithPim($event) { $variationName = basename($event->arguments[0]); if('pim_'!=substr($variationName,0,4) || false!==$event->return) { // if the result of hooked method isn't false, or if the file doesn't start with 'pim_' we leave now return $event->return; } // ok, imagefile starts with 'pim_', does it belong to the pageimage? $pageimage = $event->object; // get the pageimage $basename = basename($pageimage->name, '.' . $pageimage->ext); // basename of pageimage $re = '/^pim_.*?' . $basename . '.*?' . '\.(gif|jpg|png)' . '$/'; // regexp to identify if it's a valid pim_variation if(preg_match($re, $variationName)) { // we have a match, now return array with imageinfo // (the following rows are taken from original method Pageimage::isVariation(), only regexp is modified) $re2 = '/^pim_.*?' . $basename . '\.' . // pim_(prefix)_myfile. '(\d+)x(\d+)' . // 50x50 '([pd]\d+x\d+|[a-z]{1,2})?' . // nw or p30x40 or d30x40 '\.(gif|jpg|jpeg|png)' . // .ext '$/'; preg_match($re2, $variationName, $matches); $info = array( 'original' => $basename . '.' . $pageimage->ext, 'width' => $matches[1], 'height' => $matches[2], 'crop' => (isset($matches[3]) ? $matches[3] : '') ); $event->return = $info; return $event->return; } return false; } The next release of PiM (0.1.1) will have that.
    1 point
  27. I'd like to see this module get some love, so if someone wants to help Antti, I can donate a couple of hundred euros.
    1 point
  28. Same error here, but love it! Best PW theme out there, should be improved and become default
    1 point
  29. Because permission inheritance is determined at runtime. Two pages using the same template can inherit different permissions based on what templates their parent pages are using. To put it differently: when a page is using a template that does not define access, then that page is going to inherit the access from the nearest parent page using a template that does define access. As a result, if you only define access on your homepage template (which is the default setting) then those access settings are inherited throughout the entire site. But then if you had a page called /private-stuff/ that was using a template called "private", and that template defined access, then any pages below /private-stuff/ would inherit the access defined on the "private" template. The only exception would be if one of those pages used another template that itself defined a different access.
    1 point
  30. Just in case there is anyone else who needs to search comments. I pieced together some stuff Soma and Ryan had posted in other topics. Here is a DB query workaround: $query = $db->query("SELECT pages_id FROM field_comments WHERE data LIKE '%SomeStringHere%' ORDER BY created"); $ids = array(); while($row = $query->fetch_row()) $ids[] = $row[0]; $results = $pages->getById($ids);
    1 point
  31. I have written a little module that extends Somas awesome Images Manager. Also it's written with Somas kind help, (thanks!) It adds auto filling of EXIF or IPTC fields where available on upload of new images through Images Manager. How to use it: You, of course have Images Manager installed and ready to run. Now you have to create some fields that should take your exif data: fieldname prefix is exif_ followed by the original exif-fieldname but lowercase! ( exif_author, exif_copyright, etc.) ALSO you have to create one TextArea field called (by default) image_exif, - this one and ... (not needed, only optional to get the full raw EXIF-data stored) all your exif_fields you have to add to the image-template that is used by Images Manager for creating the new Image Pages. then download and install the ImagesManagerMetadata module. here are a little screencast I've done with it: https://youtu.be/wjhJdT7Tf5Y this is alpha, version 0.0.2 ImagesManagerMetadata.zip
    1 point
  32. ProcessWire will do all of this, but Pete is right that you'd have to do it from the API side rather than click to setup. Probably what I will do is build some more formal workflow modules in upcoming versions of PW that do it out of the box but also give you a good starting point to modify from. Currently it's fairly trivial in ProcessWire to setup a workflow for approval of new pages to be published. But setting up the workflow for approval of modifications to already-published pages takes much more on the API code side.
    1 point
  33. Ryan, Thank you for your help! It ended up being something different. I changed my form tag to the following at it works now. hooray! <form action="" method="POST" enctype=multipart/form-data> I didn't originally have the enctype=multipart/form-data in there. I don't know what I was thinking.
    1 point
  34. Nice discussion, thanks for posting guys. Our setup is pretty much similar to Ryan's (got good tips there when build it), although I have little bit of Soma's method baked in too If I take Ryan's example, then our main.php would be something like this: <html> <head> <title><?php echo $page->title; ?></title> </head> <body> <h1><?php echo $page->title; ?></h1> <?php if ($page->tpl) include("./tpl/{$page->tpl}.inc"); else include("./tpl/default.inc"); ?> </body> </html> Then I would set that $page->tpl in actual template file (like product.php, event.php etc), if I need to. Of course it would also be possible to allow client to choose tpl on certain page templates (using basic page field selection), but I haven't had the need yet. This way I can use same basic wrapper even though markup inside body tags would be totally different. This also allows to have $page->tpl as selection for page editors if that is needed (not yet the case). Most of the time it seems that default.inc works 90% of the time.
    1 point
  35. 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...