Leaderboard
Popular Content
Showing content with the highest reputation on 09/25/2017 in all areas
-
I wasn't sure about replying because you are giving wordpress a lot of attention here. But reading your a) and b) I have my 5 cts worth it: That's what I thought also years ago until I learned otherwise. Bumping into a client who wants it done in wordpress: trying to convince a client doesn't work. I spent no longer than 5 minutes opening the door to processwire, then I leave my card and move on. There are unlimited small offices and businesses out there who still don't have a website. Not true. Have a look at the api of processwire. Any experienced coder will pick up the api of processwire in no time. Processwire is decoupled so nothing to learn on the front. Just pick any framework or code your own css. And that is exactly what I tell my clients: If I am not around anymore all you have to do is to find an experienced coder and your website will go on. Heck, I bet an experienced coder will pick up the api of processwire faster than wordpress.4 points
-
4 points
-
Created an issue and pull request with a fix https://github.com/processwire/processwire/pull/91 https://github.com/processwire/processwire-issues/issues/3853 points
-
To remove the breadcrumbs, and change headline and browser title: $this->addHookBefore('Process::execute', function (HookEvent $e) { /** @var Process $process */ $process = $e-object; if ($process != "ProcessModule") return; $e->wire('breadcrumbs')->removeAll(); $e->wire('processHeadline', 'asd'); $e->wire('processBrowserTitle', 'asd'); }); You can't really remove headline and browser title, because admin theme defaults to page name if it doesn't exist. // AdminThemeDefaultHelpers.php /** * Get the headline for the current admin page * * @return string * */ public function getHeadline() { $headline = $this->wire('processHeadline'); if(!$headline) $headline = $this->wire('page')->get('title|name'); // ... } /** * Render the browser <title> * * @return string * */ public function renderBrowserTitle() { $browserTitle = $this->wire('processBrowserTitle'); if(!$browserTitle) $browserTitle = $this->_(strip_tags($this->wire('page')->get('title|name'))) . ' • ProcessWire'; // ... } But you can set it to a unicode space character, like which works well enough. $e->wire('processHeadline', " "); $e->wire('processBrowserTitle', " ");3 points
-
This week we've got new versions of the Uikit 3 admin theme, a new version of ProCache with SCSS and LESS support, plus a brand new module that provides user login, new user registration and a user profile editor, all for the front-end of your site. And of course, a new core dev version too (3.0.76)! https://processwire.com/blog/posts/pw-3.0.76-plus-login-register/2 points
-
Be warned, this is a bit of a ramble but interested to hear other points of view. It's not a 'I hate wordpress' post at all, we all know each project needs tools, and they are chosen depending on the project. https://www.cmscritic.com/processwire-vs-wordpress/ So, I've as looking at this old post yesterday and see a few of the regulars here getting involved I installed wordpress yesterday and have spent the best part of this morning getting to grips with some basic stuff. Anyway, I'm thumbing through the twentyseventeen theme and I can't help but be extremely confused by the whole thing. My mind is blown how overly complex it seems to display what is a big header image, with some posts under it and a sidebar. There's a 567 line functions file that does something or other. Is it a case of the theme has to support a zillion different things a user "might" do, when the processwire approach is to theme the site with exactly the requirements of a given project? Of course I don't have a lot of experience with custom themes in wordpress but I'm thinking it would take a good year or so (at least for me) to get proficient at this. Why am I doing this? Purely because (a) it's so popular and I can't avoid the possible work opportunities and (b) I have doubts that convincing people to use processwire is going to work. Mainly because I can't answer the question "who will take care of my site when you're gone". This is a legit question for a business owner and I feel this is also a big problem for a system that has a far lower userbase and (c) I'm love trying out different CMSs. i compared the UI side by side: What I liked about the above is that this is showing all 'Pages', and is listed as such. The above however also list 'Pages', because everything in processwire is a page. I think that 'Add new' should immediately popup on hover though like the way wordpress does. I can't much any point going to '/page/add/'. I also think 'Tree' should be removed entirely (when AOS module is used with 'Always show sidebar items'). The 'Page' link at the top goes to the same page and what does 'Tree' mean to a user? Off topic, but I find the Reno module awkward to use compared to the default admin theme. The accordian in the left menu requires a lot more clicking than the default theme hover/dropdown combo. However, Reno becomes a lot more useful with AOS and looks great. The actual editing process interested me as I remember wordpress being really easy to do this: This time though after using PW for a year is that there is too much distraction here. My eye wanders over to the right. The worst bit here is having to select a parent page every time you create a child page, that would pain me somewhat. I want to be able to select a parent and directly create a child (like Drupal or PW). I almost missed the 'Featured image' bit down there to the right (although it can be dragged up). Now this is nice. Very clear, a user will just move down the page, editing as they go. No need to worry about 'Parent' or 'Order' options (in WP). Another thing I notice as there doesn't seem to be any relationship to wordpress pages and posts. You can change the URL to posts to display on 'site.com/posts/my-post' but there is no 'posts' parent page. I find this quite confusing. Global categories can be set ( with a bunch of code https://stackoverflow.com/questions/16802751/multiple-custom-post-types-one-set-of-categories ) so your custom post types can use a single list of categories across the whole site. however, the categories are stored under 'Posts' in the admin bar to the left. So, in effect, they're global but don't LOOK global. Another +1 for my confusion. Custom fields (acf: repeater and repeater matrix, aka 'Flexible content field'... are only in pro version), custom post types (cpt), security (wordfence), user management (roles/permissions). I need plugins for all of those. There are plugins that do really simple stuff that cold be done in a few lines in PW. Although widgets look cool with the drag and drop, I'm not sure I'd actually want a client adding extra stuff all over the place on their site in sidebars etc. Setting image sizes, controlling image uploads are things I would expect in a CMS, not requiring extra functions to achieve. I mentioned earlier and this one is a killer for me, I hate this. I found a system that I'm productive with, it totally clicks with my brain, I can use any frameworks, any themes, make one from scratch, whatever, yet: (b) I have doubts that convincing people to use processwire is going to work. Mainly because I can't answer the question "who will take care of my site when you're gone". This is a legit question for a business owner and I feel this is also a big problem for a system that has a far lower userbase. So how do other people on the forum approach the above point? Currently looking at:2 points
-
possibly, read on... If you are comparing 'the' UI side by side, the problem is that there is no 'the' ui, because the page tree is the default UI, however when i build a site, my clients log into an admin that shows a dashboard (like wordpress), with lots of shortcuts to common areas, as well as content creation (like 'New Blog Post'). Some of these clients have never seen the page tree. ListerPro is a little bit like the wordpress listing of pages (albeit without hierarchical indents), but 'on steroids' – instantly filter to any page by title, use the filters or lister actions, edit inline, and ... bob's your uncle.2 points
-
Why is there no simple preview button? For simple websites I dont need the features of the ProDrafts. I think, it should be in the core.2 points
-
You need to use $page argument. Also remember to check if field is actually the field you want. wire()->addHookAfter('InputfieldRepeater::renderRepeaterLabel', function (HookEvent $e) { /** @var Page $page */ $field = $e->object->hasField; // check the field if ($field != "events_detail_dates") return; $page = $e->arguments('page'); $e->return = date('D. j F Y', $page->events_detail_dates_start_date); });2 points
-
You can hook into InputfieldRepeater::renderRepeaterLabel and change $event->return. wire()->addHookAfter('InputfieldRepeater::renderRepeaterLabel', function (HookEvent $e) { $field = $e->object->hasField; // check the field if ($field != "myRepeaterField") return; /** @var Page $page */ $count = $e->arguments('cnt'); $page = $e->arguments('page'); $labelDate = date('y-m-d', $page->published); $label = substr($page->getText('title|body'), 0, 20); $e->return = "{$label} -- {$labelDate}"; }); Which renders as From the core: // InputfieldRepeater.module /** * Render the repeater label * * @param string $label Default label * @param int $cnt Item index (1-based) * @param Page $page Repeater item * @return string * */ public function ___renderRepeaterLabel($label, $cnt, Page $page) { ... }2 points
-
@MilenKo You can just use translation functions for this: echo _n('person', 'persons', $page->comments->count); From the core: // LanguageFunctions.php /** * Perform a language translation with singular and plural versions * * @param string $textSingular Singular version of text (when there is 1 item) * @param string $textPlural Plural version of text (when there are multiple items or 0 items) * @param int $count Quantity of items, should be 0 or more. * @param string $textdomain Textdomain for the text, may be class name, filename, or something made up by you. If omitted, a debug backtrace will attempt to determine automatically. * @return string Translated text or original text if translation not available. * */ function _n($textSingular, $textPlural, $count, $textdomain = null) { return $count == 1 ? __($textSingular, $textdomain) : __($textPlural, $textdomain); }2 points
-
https://www.baumrock.com/portfolio/individuelles-crm-und-controlling-tool/ I'm happy to share my biggest and most interesting ProcessWire project so far with you It's a 100% custom office-management solution that helps my client to keep track of all their contacts, projects and finance/controlling stuff. Conception was done back in 2016 and the software is productive since begin of this year. My client is very happy with the result and so am I. Some technical insights: Everything is done inside the PW Admin. I'm using the Reno Theme with some custom colors. In the beginning I was not sure if I should stay with the pw admin or build my own admin-framework but now I'm VERY happy that I went with PW Almost all of my custom Process Pages use my RockDatatables module - there are still some limitations but without it, this project would not have been possible For the charts I used Google Charts and chartjs - both play well together with the datatables and make it possible to display filtered data instantly: also my handsontable module was created for this project to have a nice and quick option for matrix data inputs: Lister and ListerPro were no options as i needed much more flexibility regarding data presentation (like colorization, filtering and building sums of selected rows): invoices are highly customisable as well and easy to create. PDFs are created by php and mPDF by the way: all data is dummy data populated via my Module RockDummyData have a nice weekend everybody1 point
-
Taking the cue that came up in this thread, I'm taking this first step to evaluate if we have something to go on as to create a new site for our beloved PW. First of all, we'll need a blessing from our godfather Ryan. Then we need to establish a proper team with roles. I'm taking the first step but by no means placing myself as leader of the project. So I propose that whoever wants to contribute, step forward and say what role(s) you can contribute to in this adventure. Myself, having a background in creative direction and frontend development, I can contribute in planning, design, copywriting and frontend dev. To lead the project, I'd tip the hat to one of the veterans everyone knows.1 point
-
A simple recursive function that walks over all image fields and those inside repeaters(including FieldtypeFieldsetPage) to find images tagged with a certain tag(s). It can easily be extended to file fields by changing instanceof FieldtypeImage to FieldtypeFile, or be restricted to file fields by adding a !$type instanceof FieldtypeFile, too. Adapted from ProcessPageEditLink::getFilesPage() method. /** * Find all images tagged with a certain tag in a page including repeater items. * * @param $page Page to search tagged images * @param $tag string|array Image tag(s). Can be 'foo' for single, 'foo|bar' for multiple OR tags, 'foo,bar' or ['foo', 'bar'] for multiple AND tags * @return array Tagged images in [basename => Pageimage] associated array form or empty an array */ function findTaggedImages(Page $page, $tag) { $tagged = []; foreach ($page->template->fieldgroup as $f) { $type = $f->type; if ($type instanceof FieldtypeImage) { /** @var Pageimages $images */ $images = $page->{$f->name}; if (!$images) continue; $tagged = array_merge($tagged, $images->findTag($tag)->getArray()); } else if ($type instanceof FieldtypeRepeater) { $items = $page->{$f->name}; if (!$items) continue; if ($items instanceof PageArray) { foreach ($page->$f as $item) $tagged = array_merge($tagged, findTaggedImages($item, $tag)); } // FieldtypeFieldsetPage returns a single page instead of a PageArray elseif ($items instanceof Page) { $tagged = array_merge($tagged, findTaggedImages($items, $tag)); } } } return $tagged; } And can be used as $featuredImages = findTaggedImages($page, 'featured'); // get first featured image $featured = reset($featuredImages); // or array_shift($featuredImages)1 point
-
Or just provide an ASM multi-select field with a list of the fields that the client can order as they desire. You could do this manually with an Options fieldtype, or perhaps with this: http://modules.processwire.com/modules/fieldtype-fields/ which lets you limit the listed fields based on a selector. You could add this field to a separate "Field Order" tab to keep things clean. Of course then you order the output of the fields in your template file based on the order they have selected.1 point
-
If a client is dead-set on WordPress, it's worth communicating to them that every developer has their own go-to approach with the system, to the point where I would say it's not even "WordPress" anymore. So even if another developer were to take over it, it's still foreign territory to an extent, followed up with continuously saying "why the hell did the previous developer do things in X way instead of Y?" and a lack of productivity. Just check out all the starter themes, mega themes (ugh... ... ... ugh), and different approaches to custom fields. It's pretty terrible. For me, ProcessWire + UIkit solves like 95% of my challenges, and solves them WELL.1 point
-
1 point
-
1 point
-
Great selling point for wp theme coders "iphone x compatible"1 point
-
Here is an official post about designing websites for iPhone X. It should be mentioned, that this is optional.1 point
-
Something like for($i = 0; $i < $imagesCount; $i++) { $img = $p->imagesMain->eq($i); $descr = $descriptionsFiltered[$i]; $img->description = $descr; } ?1 point
-
Hello, I made this clone of the Ghost Blog System (http://ghost.org) for demo of the Wire Render Pattern as well as a multi language site and menu system. https://github.com/NinjasCL/pw-ghost As always MIT licence.1 point
-
Hmm. I am having the same issue. I did some debugging. It looks like the module is working as intended, and sending response to frontend with 'data-nosize' attribute set correctly. But in pwimage plugin for CKEditor, nosize setting isn't used at all. // pwimage/plugin.js function insertImage(src) { var $i = $iframe.contents(); var $img = jQuery("#selected_image", $i); // ... var $insertHTML = jQuery("<img />").attr('src', src).attr('alt', alt); // ... if (width > 0) $insertHTML.attr('width', width); // ... editor.insertHtml(html); // ... }1 point
-
1 point
-
Hi Abdus, Actually I assumed that so, when testing, I removed the image from the page completely and added an all new one. Same result, the width attribute still keeps being added.1 point
-
@pwFoo MarkupCache only supports strings and uses files for storage. WireCache supports arrays (of non-objects), PageArray and strings and uses DB for storage. WireCache is the way to go.1 point
-
Template cache is bound to the template of the current page. When rendering a page, regardless of how many files you render or include, only the markup that is output to the browser will be cached into a file (can be found in /site/assets/cache/Page/<id>), so that the render routine can be skipped if request can be responded with the cached output. If you want to cache arbitrary bits of markup you can use WireCache class with $cache API variable, or use MarkupCache module. $layout = $cache->getFor($page, 'layout'); if (!$layout) { $layout = $files->render('layout.tpl', [ 'title' => $page->title, 'content' => $page->body ]); $cache->saveFor($page, 'layout', $layout, WireCache::expireDaily); } One thing to note is that template cache, by default, is disabled when you're logged in. https://processwire.com/api/ref/wire-cache/ https://processwire.com/talk/topic/7-new-markupcache-module/1 point
-
Hmm, it still works without wireInstanceOf() (which I believe is used for PW2 compatibility), but one bug I've found is that since FieldtypeFieldsetPage is a single repeater item, it doesnt return a RepeaterPageArray, instead returns the only item. Adding a check fixes it else if ($type instanceof FieldtypeRepeater) { $items = $page->{$f->name}; if (!$items) continue; if ($items instanceof PageArray) { foreach ($page->$f as $item) $tagged = array_merge($tagged, findTaggedImages($item, $tag)); } // FieldtypeFieldsetPage returns a single page instead of a PageArray elseif ($items instanceof Page) { $tagged = array_merge($tagged, findTaggedImages($items, $tag)); } } Updated the code in OP1 point
-
Shouldn't that be: } else if ($type instanceof FieldtypeRepeater || $type instanceof FieldtypeFieldsetPage) { or perhaps: } else if(wireInstanceOf($type, 'FieldtypeRepeater')) { to support FieldtypeFieldsetPage?1 point
-
1 point
-
First, let me say that I've been looking forward to a module like Login/Register/Profile. I think a module like this one helps to bring another category of projects to ProcessWire that otherwise would have been developed in another CMS. I've been playing with the module over the weekend and discovered the following: Opening "Fieldset in Tab" fields display as an option in the module's "Profile form fields" setting. Ending "Fieldset in Tab" fields display with the label "Close an open fieldset". I'm going to assume that "Fieldset in Tab" fields should not display as an option. If an image is added via the "Profile form fields" setting, the default display of that image on the public side displays the Edit functionality for the image. Can this be turned off? If an image's settings restrict the image's dimensions, the image does not display appropriate errors if a larger or smaller image is uploaded. I feel that images need to work well with this module since profiles on most services these days include an option for a profile image. Thank you for making this available!1 point
-
Hi Ryan, Great to see the registration/login module - very appreciated. In the next version, could you make the createConfirmationCode() method hookable so we can supply our own generators? Actually, only the generation of the code needs to be hookable - the scaffolding in that method to store the generated code could stay as it is. Many thanks!1 point
-
It uses ProcessWire's API to send the mail. If you need specific SMTP settings, you'll want to install one of the WireMail modules from the modules directory, whichever one suits your needs best.1 point
-
$yesterdayEvening = strtotime('yesterday 21:00'); $todayEvening = strtotime('today 21:00'); $latest = $pages("<your selector>, created>=$yesterdayEvening, created<=$todayEvening"); http://php.net/manual/en/datetime.formats.relative.php1 point
-
Hey, thanks for the input. I was putting my head into it quite a few time yesterday, and messed up something. Took a while to figure it all out today. It can get complicated. You refactor stuff, then suddenly it all messed up. I commited a new version with some of your input and various fixes. https://github.com/somatonic/Aligator/commit/dc4d8aa19ff665e24aa07ccba65fd3aff0d4e002 The static level I also recognized that it gives problem when using more than one menu. Also the default options now carry over all levels. I don't think a "all" array is needed just for that, since it was the intention to have a default that is the fallback. I added a $states variable to callback (third argument) that returns a string with classes for the different states. You can enable it and configure it too. Something like this was my testing scenario: /** * load Alitgaor module * -------------------------------------------------------------------------------- */ $nav = $modules->Aligator; /** * first menu * using PageArray for first level and prepend root page * -------------------------------------------------------------------------------- */ $menuPages = new PageArray(); $home = $pages->get("/"); $menuPages->add($home->children("template=basic-page")); $menuPages->prepend($home); $nav->enableStates = true; // enable states ("parent current has_children first last") $nav->levels = 3; // set max levels to render // the default options for all levels $nav->setDefaultOptions(array( "selector" => "template=basic-page", "callback" => function($item, $level, $states){ // $states is a string of item state classes to insert somewhere $classes = $states ? " class='$states'" : ""; return array( "item" => "<a href='$item->url'>$item->title</a>", "listOpen" => "<li$classes>", "listClose" => "</li>", "wrapperOpen" => "<ul class='dropdown'>", "wrapperClose" => "</ul>", ); } ) ); // render the menu $content .= $nav->render($menuPages, array( array( // level1 "selector" => "template=basic-page", ), array( // level2 "selector" => "template=basic-page|article" ) )); /** * render different menu with default options and using a root page * -------------------------------------------------------------------------------- */ $nav->levels = 4; $nav->collapsed = true; $nav->setDefaultStates(array("is_current" => "active")); $nav->setDefaultOptions(array( "selector" => "template=basic-page", "callback" => function($item, $level, $states){ return array( "item" => "<a href='$item->url'>$item->title</a>", "listOpen" => "<li class='$states'>", "listClose" => "</li>", "wrapperOpen" => "<ol>", "wrapperClose" => "</ol>" ); } ) ); $content .= $nav->render($pages->get("/")); I'm not sure, there's possibly still something that isn't covered or I missed but seems working fine here. Thanks1 point
-
That's a remnant from times with PHP < 5.4, where the register_globals setting in php.ini was still often set to true. This meant that every GET or POST parameter was added as a global variable of the same name. If programmers were just a tiny bit sloppy and forgot to initialize their global variables with reasonable default values, this lead to security issues since malicious visitors could set their desired values. A simple example would be a PHP script with an authorization check. Let's suppose our hacker calls it with the URL http://my.broken.site/page.php?auth=1 <?php // Authorization check if(is_user_authorized()) { // we only set $auth to a truthy value when the check was successful $auth = true; } if($auth) { show_sensitive_content(); } In that example, $auth isn't set to anything if is_user_authorized fails, so our hacker created a global variable $auth from the GET parameter with a truthy value (1) and that never gets overwritten. He can see our sensitive content. Ouch. To prevent these kinds of problems, it was good practice to remove all globals before populating your own.1 point
-
You can upload your site files after zip, via scp also scp local_site.zip runcloud@server-ip-address:webapps/your-web-app-path/ If you read documentation, database section you can see the answer : https://runcloud.io/docs/server/database.html#rc-docs-scroll You need to add 3306/tcp port, like here. after add port to your firewall settings, you can connect your database with your server ip from anywhere. You can use Sequel Pro app for connect to your database. After you done with database, don't forget to remove 3306/tcp port!1 point
-
HELLO. I've recently found that the module doesn't currently work as expected. please do not use till this is resolved. Thanks Should work now. wasn't saving pages properly, but now fixed.1 point
-
I've just extended FieldtypeTime and InputFieldTime by support for blank values Failed to add a push request to https://github.com/netcarver/PW-FieldtypeTime, so please find my patch attached ... Works fine at me. PW-FieldtypeTime-Empty-times.patch1 point
-
Hello OLSA, I don't know exactly how the structure of your template folder is, but I had the same error message "Call to undefined function __()", when I tried to use an translatable string inside an php include file like this: echo __("String to translate"); I solved this error by using the $this->_() wrap mentioned in the documentation: echo $this->_("String to translate"); Maybe this will solve your problem. Personally I never had problems with the template compilation, but If you have and want to disable the template compilation, you should be sure to add the ProcessWire namespace at the beginning of your template files. I wouldn't disable the module compilation, because most of the modules aren't yet compatible with PW3 without the module it. If Wamp supports PHP7 you could try if it improves your back end performance. Regards, Andreas1 point
-
In his latest blog post, Ryan annouces his works on the ProDraft-module for handling publishing workflows. While this is really great news, there is, at least in my opinion, the drawback that this module is a Pro-module. I really appreciate the tons of work Ryan puts into PW and see the need for getting some money back not being able to do work for some clients. I also like the idea of the Pro-modules, where advanced functions not needed by anybody is sold at a moderate price, i myself have bought some Pro-modules already. But such fundamental functionality like draft-versioning or defining a workflow for publishing should be in the core and made open source. I would like to raise a discussion about this, how it could be solved or what other developers think. All other major open source CMS have versioning integrated, so this a field where pw lacks behind and the chance with making that in core would open more opportunities for attracting more people using PW. But then getting this functionality only by paying a decent amount could draw them immediately back without getting the beauty of PW: Some solutions to solve this that cross my mind: Sponsoring: Already Avoine has sponsored some other modules being developed by Ryan, so maybe they or other companies that need drafting could stepin. Crowd-Sponsoring: If there is not one company or individual taking over the sponsoring, why not community fund this like a kickstarter-project? I think, most of us could spent at least the amount the Pro-module would cost or even more to make it open for public. Making only support Pro: Now all the Pro-modules get higher priority support by Ryan. Not only being the only person doing this, but maybe the only individual capable of supporting all the modules at moment, this can become a bottleneck in the future. Being open source, others can work on adding functionality and bug tracking and Ryan could concentrate on supporting. Other CMS are already doing this more or less (i.e. Acquia for Drupal). What do you think, should fundamental functionalities stay available in core for all or only being available as Pro?1 point
-
What's critical about Lister Pro? The ability to easily save a customized lister, perform bulk actions on results, and have convenient, end-user access to tabular views of large content types that are too cumbersome to manage from within the tree control. This is standard functionality in any CMS worth using, and essential for the vast majority of sites I've built over the last 20 years or so. It's a bit silly, IMO, that you can't do these things with the built-in lister. It feels intentionally crippled solely for the sake of selling the commercial component, a perception we want to avoid. I wouldn't build anything more than the most basic, trivial processwire-powered site without Lister Pro, whereas I could easily do without the other pro modules. I (sometimes) use Form Builder out of convenience, but Lister Pro out of necessity. Mind you, I'm not complaining about the cost, at all. It's entirely reasonable and I'm happy to support development. But if we're talking about the road map for the core, open source project, I most definitely view Lister Pro as essential functionality that absolutely should be part of it. I am intrigued by the idea of "graduating" pro modules to core modules via some process that combines hitting some financial goal with enough general community interest in having specific functionality available in the core. Just my two cents.1 point
-
Since you are creating a user for each author, you can simply use a page reference field for this. If a user is selected on that field, that's the one considered the author, if there is no user selected it's assumed that the author is the user that was logged when posted. $author = $page->get('author|createdUser'); //if chosen "Single page (Page) or boolean false when none selected" on the field settings Of course not all authors have to be users. You could also have a "author" template, and create all authors there. In that case you could do something like: $author = $page->author ? $page->author : $pages->get("template=author, name={$page->author->name}"); edit: none of those were tested, i just want to illustrate a concept1 point