Leaderboard
Popular Content
Showing content with the highest reputation on 04/18/2014 in all areas
-
ProCache version 2.0.0 (now in beta, available in the ProCache board) adds these new features: Multi-host support If you've got multiple hostnames pointing at your ProcessWire site, now you can cache them separately. SSL / HTTPS support ProCache will now optionally cache HTTPS requests separately from HTTP requests. Switch to PDO queries Previous versions of ProCache used MySQLi. This new version now uses PDO, consistent with ProcessWire 2.4.0. This improves performance when generating and maintaining caches. Requirements ProCache 2.0 requires ProcessWire 2.4.0 or newer. ProCache 1.x still supports previous versions of ProcessWire.8 points
-
Hi Can, Yep, that's the correct behavior. Hidden will exclude a page from $pages->find() calls, unless you specify "include=hidden" in your selector. Think of a hidden page like a page that should not be visible in your navigation or lists, but still accessible when one knows the direct URL. Unpublished really means that the page is not yet ready/published for the public, here a 404 is displayed. The same goes for pages with templates that do not have a physical template file associated. Be careful when logged in as superuser, if I remember correctly you'll see unpublished pages. In order to simulate the website for a guest visitor, you could use another browser or the private/incognito mode $pages->get() is an explicit call to retrieve a page. ProcessWire assumes that you want to get it, no matter if it's hidden or not Pw is throwing an 404 if you enter a path that does not exist. Or if a page you want to visit is unpublished or does not have a template file (because Pw does not know what markup to render). You can also throw a 404 anytime yourself, though that is already more advanced stuff. Could you maybe describe us what you want to do? Why would you want to prevent showing a 404? Cheers3 points
-
Hi reno, I think it is doable with two hooks. One hook would return false for Page::viewable() for the ProcessPageList page. Another Hook can be used to redirect your users to a custom admin page after login. I've only used the second one in a project, but I think something like this should work: // This needs to be an autoload module public function init() { $this->addHookBefore('ProcessHome::execute', $this, 'rootPage'); $this->addHookAfter('Page::viewable', $this, 'viewable'); } /** * Redirect users with custom-role to another page after login */ public function rootPage(HookEvent $event) { if ($this->user->hasRole('custom-role')) { $this->session->redirect('custom-admin-page/'); } } /** * Don't give users with custom-role access to Pages page */ public function viewable(HookEvent $event) { $page = $event->object; $user = $this->user; if ($page->id == 3 && $user->hasRole('custom-role') { $event->return = false; } }2 points
-
Can you try with 33% 34% 33%? That's what I use and haven't had an issue2 points
-
To create a sitemap.xml you can use Pete's Sitemap XML module, or you can create a template file and page to do it for you. This post explains how to create a template to do it for you. The benefit here is that you may find it simpler to tweak a template file than a module, though either is a good solution. Here is how to do it with a template file and a page: sitemap-xml.php <?php namespace ProcessWire; /** * ProcessWire Template to power a sitemap.xml * * 1. Copy this file to /site/templates/sitemap-xml.php * 2. Add the new template from the admin. * Under the "URLs" section, set it to NOT use trailing slashes. * 3. Create a new page at the root level, use your sitemap-xml template * and name the page "sitemap.xml". * * Note: hidden pages (and their children) are excluded from the sitemap. * If you have hidden pages that you want to be included, you can do so * by specifying the ID or path to them in an array sent to the * renderSiteMapXML() method at the bottom of this file. For instance: * * echo renderSiteMapXML(array('/hidden/page/', '/another/hidden/page/')); * */ function renderSitemapPage(Page $page) { return "\n<url>" . "\n\t<loc>" . $page->httpUrl . "</loc>" . "\n\t<lastmod>" . date("Y-m-d", $page->modified) . "</lastmod>" . "\n</url>"; } function renderSitemapChildren(Page $page) { $out = ''; $newParents = new PageArray(); $children = $page->children; foreach($children as $child) { $out .= renderSitemapPage($child); if($child->numChildren) $newParents->add($child); else wire('pages')->uncache($child); } foreach($newParents as $newParent) { $out .= renderSitemapChildren($newParent); wire('pages')->uncache($newParent); } return $out; } function renderSitemapXML(array $paths = array()) { $out = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'; array_unshift($paths, '/'); // prepend homepage foreach($paths as $path) { $page = wire('pages')->get($path); if(!$page->id) continue; $out .= renderSitemapPage($page); if($page->numChildren) $out .= renderSitemapChildren($page); } $out .= "\n</urlset>"; return $out; } header("Content-Type: text/xml"); echo renderSitemapXML(); // If you want to include other hidden pages: // echo renderSitemapXML(array('/path/to/hidden/page/'));1 point
-
Very simple discussion board using pw pages as topics and replies. It means that you can use the great API with your discussions also. This is VERY tiny in features, but I am open to suggestions. I want to keep this small, since there are plenty of great php based forum software around, and this tries to nail much simpler needs. What this does currently is: Multiple forums on site Multiple topics on forum Only logged in users are allowed to post Admin stuff is handled true pw-admin (everything are just pages) Replies and topics are tied to user accounts Current shortcomings: You cannot change markup easily You cannot change text / date formats etc (waiting for PW 2.2 for this) How to install Make sure you run the very latest version of ProcessWire 2.1, at least this commit or newer. Download the file from github and copy it to /site/modules/Discussions.module Go to admin -> modules and "check for new modules". After that click Install on "Discussions" It creates 3 fields and 3 templates for you. But it doesn't create 2 required template files - you need to get your hands dirty. Create two new template files: discussions-forum.php and discussions-topic.php Edit your new templates and add this line to both of those: echo $modules->get("Discussions")->render(); Create a new page and give it template: discussions-forum You probably want to add Markdown Extra textformatter to your discussions_message field. (Ryan, how to do this from install script?) That is pretty much it. It will look ugly as hell, so you really want to add & edit some css (very basic starting point provided below) /* DISCUSSIONS -basic styling */ #discussions { position: relative; width:100%; overflow: hidden; } .discussions-reply, .discussions-form { padding: 20px 0; border-bottom: 1px solid #ddd; clear: both; overflow: hidden; } .discussions-form { border: none; } .discussions-information { float: left; width: 20%; overflow: hidden; } .discussions-author { font-weight: bold; display: block; } discussions-datetime { font-size: 0.9em; color: #666; margin-bottom: 1.5em; } .discussions-message { border-left: 1px solid #eee; padding-left: 3%; margin-left: 2%; width: 74%; float: left; } .discussions-form label { display: block; } .discussions-form textarea { width: 90%; } #discussions .discussions-message p, #discussions .discussions-message table, #discussions .discussions-message ul, #discussions .discussions-message ol { margin-top: 0 !important; } /* Pagination */ .MarkupPagerNav { margin: 1em 0; font-family: Arial, sans-serif; overflow: hidden; } .MarkupPagerNav li { display: inline; list-style: none !important; margin: 0 !important; } .MarkupPagerNav li a, .MarkupPagerNav li.MarkupPagerNavSeparator { display: block; float: left !important; padding: 2px 9px; color: #fff !important; background: #2f4248; margin-right: 3px; font-size: 10px; font-weight: bold; text-transform: uppercase; } .MarkupPagerNav li.MarkupPagerNavOn a, .MarkupPagerNav li a:hover { color: #fff; background: #db1174; text-decoration: none; } .MarkupPagerNav li.MarkupPagerNavSeparator { display: inline; color: #777; background: #d2e4ea; padding-left: 3px; padding-right: 3px; } This was very fast to code (I estimate 6 hours, certainly under 8 hours). I consider this version as a alpha, not tested that much (well, it works on my computer ) and I do wanna add some features and get feedback (how it works, any security issues etc). All feedback is welcome.1 point
-
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. Cheers1 point
-
Max, you raise some good points (that have actually been raised before ). I'll comment on two of them: And you are absolutely right. Remember though that PW is still a young system (in relation to it being released open source, i.e.). As with most systems, you first start with making sure that the API documentation is rock solid. This is what PW has done (in my observation). You pick up the API and run with it. Ryan (or somebody else, can't remember) summed it up beautifully in some post. Rather than teach someone how to put together a photo gallery, or a school website, you'd rather give and teach them the tools (API) to put together ANY type of site . You master the API, you master everything (even beyond PW since there is no templating language - it's just OOP PHP). But, there is a place for 'how to' tutorials. However, with the relatively few hands on deck compared to other similar projects, it is impossible to equally concentrate on the API documentation, 'how to' tutorials and answering questions in the forums, not to mention continuing the development of the core PW code. Hence, so far, 'how to' tutorials have largely remained a community effort. Joss has really tried to write a few. He has also posted in the forums an excerpt from his upcoming 'how to' PDF. I also have a few 'how to' tutorials in the pipeline (as you can see from my rather dormant website www.kongondo.com ). We can do with a few more Marys to tell the truth... Good point. And this is one big difference between systems that employ templating systems (like MODx) and pure OOP based systems like PW. When MODx started to crumble under my feet, I was asking myself this same question. I took the plunge into PW and here we are having this conversation. What I have learned using PW is a transferable life skill (seriously). It is like HTML or CSS. It is universally applicable. I never have to learn another templating system. This means I can (relatively easily) pick up any OOP PHP system with good API documentation were PW to disappear tomorrow.... I am happy you are not giving up yet on PW. Yes, to use it, you will have to invest time in it....but we'll be here to guide you every step of the way1 point
-
Except for name, all fields in ProcessWire Pages are custom fields . Yes, even Title is a custom field....Unless you specify a field as hidden, all fields added to a template will be available to all pages using that template....in the order you sorted them in the template. And here's a bonus for you....that doesn't mean that when you view that page (am talking frontend)...that you will see any fields automatically. Nada...you will have to output them yourself in your template file in the order you want, if you want! Sorry, I got carried away there for a minute...Enjoy!1 point
-
1 point
-
I think you would have to stick Pw in a subfolder then but you would get the subfolder name in your Pw page urls. Or was that what you mean in your question? How to remove the subfolder from the Pw urls?1 point
-
Git annex is soon truly cross-platform: https://git-annex.branchable.com/install/ Sparkleshare might not be for you, but good to review nonetheless: http://sparkleshare.org/ Kolab also has a file cloud now, but maybe it has too much other stuff for your taste: http://kolab.org/news/2014/04/09/kolab.org-3.1-released-file-cloud-plenty-irony1 point
-
@felix, I haven't used it but, coincidentally, this week's episode of FLOSS Weekly is about Seafile.1 point
-
Vagrant is a great piece of software and for sure makes many things easier (as mentioned in the tao). It's just not fitting into OUR process and workflows. If you're (for example) working on one or two bigger projects at the same time with a large team of people vagrant would be a perfect fit for that.1 point
-
Best to start with guidelines to stay out of trouble. GOOGLE : http://www.webmasterworld.com1 point
-
I recently found while doing work on Laravel a nice tool called Var Dumpling that will convert all var_dumps to nicely formatted blocks of text with a structure, making it a lot easier do debug var_dumps. It's available on Chrome and Firerox, you can see what it looks like on their page http://vardumpling.com/ Hope some of you find it interesting!1 point
-
There might be some development coming for this module, but not planning to commercial this (not even able to, since this is build mainly on my work time). What features you are interested in?1 point
-
Go on then! Currently I'd use Batcher or CSV Import to do that. You way sounds much quicker.1 point
-
They'll be covered by the license of ProcessWire itself, so go ahead and do as you like @ryan - can we make CKEditor the default editor for new installations in the next version of ProcessWire please? It's just that it's soooooooooooooo much nicer than TinyMCE1 point
-
CONGRATULATIONS TO 2.4 ! An opportunity to thank Ryan and all contributors again for this wonderful software!1 point
-
Hi Ryan, Thanks for this. I have updated my code to follow the direction with urlSegment and works amazing - cant wait until we go live soon Cheers1 point
-
Holy cow! Pro Cache is f#$@ng awesome! ... Hell nooo! Whare are no mates in my messengers list to share my joyfulness!1 point
-
Don't forget that visiting a page with chrome or the google toolbar, that is not indexed in G, will invite a crawl from googlebot. For SEO control I usually always add a field that allows the editor to set the correct meta robots for the page in the admin. And in code I will usually cascade or inherit the value of the parent unless override was present.1 point
-
Great to see and know we kinda got same spirit here, you also seem to use similar approaches! Should have posted that earlier, I think it's pretty much needed this kind of threads sharing ideas. As with other parts of PW that still seem to be undiscovered for some people. (was surprised some people here didn't knew there were a tabfield they could use). Not that I think is a problem, but maybe we should start getting/pointing those things out more, even if it's just in threads like this. Back to the template thing. I also use main.php with basic html frame with head and body, and maybe a div wrapper, and the page template includes some structure that is different from page to page layout, though still it's enough flexible to extend and based on variables or template do different things like sidebars. I'm also trying out to use it the other way round much like your's Ryan. Also having structure and data more separate can help a lot. While I'm still using the echo "<p>$somevar</p>" quite a lot now in PW, I think it's not really the best way to build. Mixing php and html can lead to messy code and cluttered, noisy, harder to maintain. I'm strictly going down that road now again and still thinking about different approaches. A template parser would be handy but can create some limits at best and it's slower at the end of the day. - The other day I was trying to code one simple module to use for blog/news type listing, just for fun. Mainly to try out coding a tag parser, and ended up with the plain php and the template parser approach right in front of me, and the knowledge creating this yet simple but hard to still programm little module. I came to the conclusion, that I still prefer pure php since it can do the same with a little more code but be alot more flexible to me. – But still I'm also thinking it could simplify some tasks, and maybe still be useful to the less experiences php newcomers. It would be easy possible within PW to create markup-generating type of modules. Not sure If that should be done, as It's a little against PW's philosophie. But I really like pre-created profiles! As mentioned also in another thread, I think this could get possibly a big thing. I like the idea of having ready to go installs, and you Ryan already created the tool to export site profiles. Best part of it It can help some newcomer peoples so much, I think this should be considered quite important thing we should ignite as soon as possible. Well not trying to push things. I'm sometimes really impatient when something new excites me.1 point
-
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