Leaderboard
Popular Content
Showing content with the highest reputation on 07/31/2013 in all areas
-
Is anyone here a heavy bookmarker like I am? Typically I'll get most of my news from Hacker News and Slashdot, followed by some great blogs on a daily basis. I usually never have time to read an article in depth when I first come across it, so I'll bookmark it for later. Or, if I quickly need to get up to date on some topic, I'll do a search (usually by tags) and familiarize myself with important stuff I've bookmarked in the past. After having used browser native based bookmarking (Firefox and Chrome), then Delicious, then Diigo, then Pinboard and becoming frustrated by all of them for various reasons and limitations, I've decided to roll my own little single user (and non social) bookmarking system with ProcessWire (with Bootstrap 3 as the frontend framework). It's still a work in progress, but it takes the best of all those systems with my own power features. It also utilizes ajax for certain actions. I'll need to create a Chrome extension to tie it all together. I have to say however, after working non-stop on it for hours on end and not being able to think of anything else, it's looking slick. Damn you ProcessWire for making this so enjoyable. Jonathan6 points
-
@Zahari, Disclaimer: This below is not meant to be a criticism...just thoughts from my experience. I came in to PW from MODX and before that Drupal/Joomla and WP, etc. I feel what you are saying. Thanks for sharing your thoughts. I agree some stuff in the docs could be improved maybe with more examples. As you acknowledge, it is a community effort and any help is appreciated. On the other hand, it would be impossible to write docs for every use case. For instance, on the issue of a lack of a "categories" system you talk about, categories are predicated to systems that use them such as WP. A Drupal person will talk of where are the nodes? What about taxonomy? A MODX guy will ask for TVs and chunks. A.....you get the point . So how do we deal with this? I like what Ryan wrote in another post about focusing on the bigger picture, not the how can I do this or that. So, instead of focusing on how can I make a photo album or how can I create a menu in PW? you focus on the bigger picture, e.g. what are the basic building blocks in PW? You will notice the docs try to focus on the bigger picture. They tell you how to use the tools, those basic building blocks ($page, $pages, selectors, templates, template files and fields mainly). If you know how to use those tools you can build anything in PW. For PW, in order to effectively use its tools, you have to know some basic PHP. In other words, before you use my tools, please read the basic manual for the tools. This is nothing more than if, include, foreach, and echo. With foreach comes arrays of course. Those will suffice in most cases. However, for those willing to learn more PHP, it unlocks yet other doors and will enable you to do more with the tools. All of a sudden you can do more than echo stuff; using the API, you can delete, add, do maths, and before you know it, you have developed a small module. In essence, PW is not a turn-key solution nor does it pretend to be. On the question of more examples, I am thinking this should be a community effort (like examples on php.net). In fact, there are many examples in the forum (community contributed). Admittedly, currently it is only a handful of members who are contributing such examples. With time this will increase, I know. Hey, look at me, I only arrived recently yet I now feel comfortable enough to "contribute". I am no genius; I just learnt what I know from reading other members' contributions and the API docs . My only concern is that some of those examples will be "lost" deep in the annals of this forum. There's been community talk of collating code snippets in one place but I haven't seen that happen yet. I don't see that as a problem at all. Yes, PW assumes you have a basic knowledge of these like I said in order to effectively use its tools. In order to use this system, you need to have that knowledge. Similarly, in order to use Joomla, the system assumes you can use a mouse and a keyboard to click point and enter data . PW does not seek to replicate what those systems do. Maybe this should be made clearer in the docs if they are not clear enough. Looking forward to those videos! <btw>Come to think of it, I have seen a couple of "once this is finished I will write a tutorial to help others..." but in many cases I am still waiting for those tutorials . I am not saying the posters are not sincere; stuff just gets in the way I suppose !</btw> OK, back to WP and why I don't use it...4 points
-
I've done what horst suggested before to be honest - you don't have to worry too much about the headaches of duplicate data as all you're doing is creating a dummy PW user account and the way I did it was have one extra integer field in the PW user template to store the ID of the website account - simple as that You could then take that further if different user groups from the intranet system have different access rights on the website. I would personally make it do some checks during PW login so that: If someone enters a username and password, it checks the intranet DB and if it finds the details there but on in PW then create an account If someone is in the intranet DB but is now a disabled account, disable them in PW (unpublish) If their email has changed in the intranet DB, change their PW email address Definitely do the same with password Basically you're always authenticating against the intranet database first, and you can take it further by mapping different user groups or more as you see fit. It's the only way I'm slowly able to migrate sections of a large intranet I custom-coded several years ago to ProcessWire - so I can regain my sanity and roll out new features in a fraction of the time3 points
-
Lol at <btw> a new coding language has been born called "creative code" <read> Great post kongondo. I see here exactly the same situation as in the days with modx evo. There are those who ask for documentation improvement (complain) that it is lacking this and that and there are those who have no problems with the existing documentation. Designers and Coders. Without coding skills the documentation will always lack something and you will always have questions not answered in the documentation. The only way is to start learning to code and practice a lot. After that more and more questions will fall away. Mmmm coming to think of it maybe there is not only room for a FAQ for newbies but also group together the existing tutos and api / php coding examples in one place in the forum. Are you guys with me ?</read> May the code be strong in your projects.3 points
-
Just some thoughts: - but why can't they be real PW-users too? - You can create a specific role for them if you have other users (that not belong to the intranet) too. - You may create only one real user in PW, e.g. called 'intranet', and if the intranet-script returns valid user, you load/select this dummy-user. The real username you can store in $session. At least you are a bit rare with informations what the users should / need to do in PW, need they to be unique, do they need different roles / rights, or what else?3 points
-
I know people learn in different ways, but in my opinion, the existing documentation (it's on the site, you can't miss it) goes through all the important concepts that are needed to begin with PW. As a bonus, it even teaches you some PHP basics. After (and only after) reading the documentation, the default install is also a great place to learn. I agree that a snippets library would be very useful, but certainly not for learning. I completely disagree that we should have a place where beginners start learning how to do small tasks without completely grasping the basic concepts of $page and $pages. That's how all the bad habits begin. That's how Javascript once almost ruined the web3 points
-
Hi teppo! I can't speak for others, but for me, here is what I would say were the "pain points" that I encountered... Major issue is dealing with the "Tree - Pages - No Categories" model for the first time && ( $victim == "comes from wp" || $victim == "comes from d*" ) This took me quite a while to come to grips with. After say a month now, I have come to terms with it all and it is no longer the hurdle that it once was. But when first encountering it, the absence of categories makes it seem so damn inflexible and your thinking how and where the hell do I put my content!!! Only after reading lots of threads on how to categorize content, and reading lots of threads how to "list child pages" does the tree model all begin to make sense. So, what's missing, in my opinion is an "orientation guide" that helps you with some examples of how to lay your content out using a solid parents and children structure, ALONG with a good explanation of how to display our content and any related content alongside it. The problem here is that as there are no "categories" to begin with, ( yes, I now know you can "create" this functionality), your there wondering, if I have 100 articles, how are people going to find them? There are no categories and it would be ridiculous to have 100 artlces linked in the menu. So then you start looking at the code that is thrown in with the templates that generate a list of child pages out of neccesity. But here again lies another problem. ProcessWire too readily assumes you have a very good understanding of arrays and for foreach loops. It's just thrown at you in the starter template and for those who dont have a good understanding of arrays, you're left struggling here. To me, there is a missing guide that says, hey, there's this thing called the page array and here's whats inside it and here are a few code examples to help you access it and that using these code examples will help you list out some common requirements. For example... If your on a parent page and what to list every child of this parent, use this block of code. Now, if there are too many results, here's how you limit them by modifying that block of code here. If you want to paginate, heres how you further modify the code. Once sufficent simple examples have been built up upon, then, I believe, all the existing documentation will make MUCH more sense to beginners / newbies like me, because we have seen a set of code snippets that have "evolved" inside these examples and as such we can now readily recognize certain patterns. Once we are familiar with these patterns, then it's just going into the docs and grabbing just the bit you need cos by then, you KNOW exactly where you are going to slot it in But teppi, these are not complaints on my part. I for one hate these basthirds on YouTube who so readily criticise videos and content when they have no idea of the effort that has gone into it, nor have they produced anything themselves! My response to all this is that I want to make a couple of videos to contribute to the community here to help build a better bridge for some of those newbies who are journeying in towards ProcessWire land and are facing the same difficulties that I am. So, the first video I want to make is about explaining a bit about the ProcessWire templating system..... The second video I want to make is about how to generate a list of child pages.... Coming soon! Cheers teppo!3 points
-
Not sure if I understand correctly Just make as many thumbnails as you want from an image field. If you store the thumb separate, you have to manage two fields with the same data = bad. // Make a thumbnail 100x80 px from a field called $image $thumb = $page->image->size(100,80); echo "<img src='{$thumb->url}' alt='blub'>2 points
-
You can also redirect to the desired link. Put the page there so you have the link on the nav, and on the template: <?php $pageID = 1; $session->redirect($pages->get(10)->url.'?id='.$pageID); // 10 is the ID of the "Edit Page" page in the admin This is a simple redirection, and it's not the ideal of course...2 points
-
Yes, commenting out the 2 save lines will work. I'll take an extra look at the empty fields. Time zone settings are quite important for this module, but would only cause to publish/unpublish pages at the wrong time, but not more than 27 hours off (GMT-12 all the way to GMT+14 + possibly DST) As for the $time variable, that could be an issue. I'll change the variable name to something more unique in the next update. Update: uploaded a new version where: 1. $time has been replaced with $currenttime 2. Added language support for the whole module. /Jasper2 points
-
I use Freemind and Inkscape for basic brainstorming and planning. I planned a pretty big server migration by charting it out in Inkscape and zooming in / working on each part of the chart as work proceeded. The chart ended up looking pretty cool, and it really helped put a large piece of work behind me fast. I own a copy of Illustrator but Inkscape is better IMO as a quick vector sketchbook / illustration tool. I use a little shell script to play a sound every 20 minutes so I know to look 20 feet away for 20 seconds (20/20/20 rule). My eyes have been dry so it's helpful, and a good reminder to review what I'm working on to see where I'm at and where I need to be. I use KeePassX to store passwords, which I save in a cloud-based file hosting service so the encrypted password file is synced up on my other devices as well. I use iTerm2 instead of the default Mac OS X terminal application, and fish instead of the normal shell (csh?). I like fish so far. I use nvALT for tons and tons of journaling and note-taking. I am seeking a Mac OS equivalent of Zim Wiki though, with an enforced parent/child structure visible in the sidebar. Finally I use Blender to make animated intros for videos for my clients from time to time, and Art of Illusion to sketch out ideas for rearranging furniture in my office.2 points
-
erm foreach($pages->find() as $p) { echo "<p>{$p->url}</p>"; } returns nothing... but foreach($pages->find("*") as $p) { echo "<p>{$p->url}</p>"; } returns all. While... foreach($pages->find("has_parent!=2") as $p) { echo "<p>{$p->url}</p>"; } would exclude pages under "/processwire/" admin pages. But maybe something also some restriction to template(s) would be good. foreach($pages->find("template=basic-page|article|news") as $p) { echo "<p>{$p->url}</p>"; }2 points
-
I have done an iso for the raspberry pi with processwire installed with the basic profile, if anybody is interested in a copy just let me know.2 points
-
Hi all This module was sponsored by Jason as per this topic: http://processwire.com/talk/topic/3566-email-image-module-development/ It's quite similar to horst & ryan's EmailImage module, but supports multiple email addresses for sending emails to different parts of your site, also allowing you to select different templates. There is also a delimiter option whereby you can split up the email's content and have text appear in the body or sidebar etc. Here's a video to show you what I mean. The video may well be of interest to other module authors as I used some Ajax to push what can normally be done in the module config - hope you like it There was the temptation to build on the EmailImage module with this one, but I already had code for my Helpdesk module (work in progress) that parsed emails using Flourishlib and wanted to use that code instead for this one. EDIT: Also worth noting is that unlike the EmailImage module, this doesn't come with a pre-built gallery template for the front-end. This is intentional as you could pipe emails into any part of a site you like, so I couldn't make assumptions as to usage of the content. You can download it via the modules directory.1 point
-
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
-
Since you guys asked for it, I'll take a stab at a case study on the development process. Most of the development was done in about a week and a half. I started with the basic profile, but it ended up being something somewhat similar to the Blog profile in terms of how it's structured. Below I'll cover some details on the biggest parts of the project, which included data conversion, the template structure, the front-end development and anything else I can think of. Data Conversion from WordPress to ProcessWire One of the larger parts of the project was converting all of the data over from WordPress to ProcessWire. I wrote a conversion script so that we could re-import as many times as needed since new stories get added to cmscritic.com almost daily. In order to get the data out of WordPress, I queried the WordPress database directly (my local copy of it anyway) to extract what we needed from the tables wp_posts for the blog posts and pages, and then wp_terms, wp_term_relationships, and wp_term_taxonomy for the topics and tags. WordPress stores its TinyMCE text in a state that is something in between text and HTML, with the most obvious thing being that there are no <p> tags present in the wp_posts database. Rather than trying to figure out the full methodology behind that, I just included WP's wp-formatting.php file and ran the wpautop() function on the body text before inserting into ProcessWire. I know a lot of people have bad things to say about WordPress's architecture, but I must admit that the fact that I can just include a single file from WordPress's core without worrying about any other dependencies was a nice situation, at least in this case. In order to keep track of the WordPress pages imported into ProcessWire through repeat imports, I kept a "wpid" field in ProcessWire. That just held the WordPress post ID from the wp_posts table. That way, when importing, I could very easily tell if we needed to create a new page or modify an existing one. Another factor that had to be considered during import was that the site used a lot of "Hana code", which looked like [hana-code-insert name="something" /]. I solved this by making our own version of the Hanna code module, which was posted earlier this week. Here's an abbreviated look at how to import posts from WordPress to ProcessWire: $wpdb = new PDO("mysql:dbname=wp_cmscritic;host=localhost", "root", "root", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); $posts = wire('pages')->get('/posts/'); $sql = " SELECT * FROM wp_posts WHERE post_type='post' AND post_status='publish' ORDER BY post_date "; $query = $wpdb->prepare($sql); $query->execute(); while($row = $query->fetch(PDO::FETCH_ASSOC)) { $post = $posts->child("wpid=$row[ID]"); // do we already have this post? if(!$post->id) { // create a new post $post = new Page(); $post->template = 'post'; $post->parent = $posts; echo "Creating new post...\n"; } $post->of(false); $post->name = wire('sanitizer')->pageName($row['post_name']); $post->title = $row['post_title']; $post->date = $row['post_date']; $post->summary = $row['post_excerpt']; $post->wpid = $row['ID']; // assign the bodycopy after adding <p> tags // the wpautop() function is from WordPress /wp-includes/wp-formatting.php $post->body = wpautop($row['post_content']); $post->save(); echo "Saved post: $post->path\n"; } What I've left out here is the importing of images, topics, tags, and setting the correct authors for each post. If anyone is interested, I'll be happy to go more in depth on that, but didn't want to overwhelm this message with code. Template File Structure This site makes use of the $config->prependTemplateFile to automatically include the file _init.php before rendering a template file, and $config->appendTemplateFile to automatically include the file _main.php after. So the /site/config.php has this: $config->prependTemplateFile = '_init.php'; $config->appendTemplateFile = '_main.php'; You may recognize this as being the same setup from the Skyscrapers profile. The _init.php includes files containing functions we want to be available to all of our templates, and set default values for the regions we populate: /site/templates/_init.php /** * Include function and hook definition files * */ require_once("./includes/render.php"); require_once("./includes/hooks.php"); /** * Initialize variables populated by templates that get output in _main.php * */ $browserTitle = $page->get('browser_title|title'); $body = "<h1>" . $page->get('headline|title') . "</h1>" . $page->body; $side = ''; $renderMain = true; // whether to include the _main.php file The includes/render.php file that is included above includes several functions for generating markup of navigation and post summaries, or any other shared markup generation functions. Examples are renderPost(), renderNav(), renderTags(). This is similar to the blog.inc file from the Blog profile except that I'm letting these functions generate and return their own markup rather than splitting them into separate view files. I personally find this easier to maintain even if it's not as MVC. The includes/hooks.php sets up any hooks I want to be present for all of my templates. I could have also done this with an autoload module, but found this to just be a little simpler since my hooks were only needed on the front-end. The main hook of interest is one that makes all posts look like they live off the root "/" level rather than "/posts/" (where they actually live). This was in order to keep consistency with the URLs as they were in WordPress, so that the new site would have all the same URL as the old site, without the need for 301 redirects. /site/templates/includes/hooks.php /** * This hook modifies the default behavior of the Page::path function (and thereby Page::url) * * The primary purpose is to redefine blog posts to be accessed at a URL off the root level * rather than under /posts/ (where they actually live). * */ wire()->addHookBefore('Page::path', function($event) { $page = $event->object; if($page->template == 'post') { // ensure that pages with template 'post' live off the root rather than '/posts/' $event->replace = true; $event->return = "/$page->name/"; } }); Our /site/templates/_main.php contains the entire markup for the overall template used site wide, from <html> to </html>. It outputs those variables we defined in _init.php in the right places. For example, $body gets output in the <div id='bodycopy'>, $side gets output in the right <aside>, and $browserTitle gets output in the <title> tag. /site/templates/_main.php <?php if($renderMain): ?> <html> <head> <title><?=$browserTitle?></title> </head> <body> <div id='masthead'> // ... </div> <div id='content'> <div id='bodycopy'><?=$body?></div> <aside id='sidebar'><?=$side?></aside> </div> <footer> // ... </footer> </body> </html> <?php endif; ?> We use the rest of the site's template files to simply populate those $body, $side and $browserTitle variables with the contents of the page. As an example, this is an abbreviated version of the /site/templates/post.php template: /site/templates/post.php // functions from /site/templates/includes/render.php $meta = renderMeta($page); $tags = renderTags($page); $authorBox = renderAuthor($page->createdUser); $comments = renderComments($page); $body = " <article class='post post-full'> <header> <h1>$page->title</h1> $meta </header> $page->body $tags $authorBox $comments </article> "; if(count($page->related)) { $side = "<h4>Related Stories</h4>" . renderNav($page->related); } What might also be of interest is the homepage template, as it handles the other part of routing of post URLs since they are living off the root rather than in /posts/. That means the homepage is what is triggering the render of each post: /site/templates/home.php if(strlen($input->urlSegment2)) { // we only accept 1 URL segment here, so 404 if there are any more throw new Wire404Exception(); } else if(strlen($input->urlSegment1)) { // render the blog post named in urlSegment1 $name = $sanitizer->pageName($input->urlSegment1); $post = $pages->get("/posts/")->child("name=$name"); if($post->id) echo $post->render(); else throw new Wire404Exception(); // tell _main.php not to include itself after this $renderMain = false; } else { // regular homepage output $limit = 7; // number of posts to render per page $posts = $pages->find("parent=/posts/, limit=$limit, sort=-date"); $body = renderPosts($posts); } The rest of the site's template files were handled in the same way. Though most were a little simpler than this. Several were simply blank, since the default values populated in _init.php were all that some needed. Front-end development using Foundation 4 The front-end was developed with the Foundation 4 CSS framework. I started with the Foundation blog template and then tweaked the markup and css till I had something that I thought was workable. Then Mike and I sent the _main.php template file back and forth a few times, tweaking and changing it further. There was no formal design process here. It was kind of a photoshop tennis (but in markup and CSS) where we collaborated on it equally, but all under Mike's direction. After a day or two of collaboration, I think we both felt like we had something that was very good for the reader, even if it didn't originate from a design in Photoshop or some other tool like that. I think it helps a lot that Foundation provides a great starting point and lends itself well to fine tuning it the way you want it. I also felt that the mobile-first methodology worked particularly well here. Comments System using Disqus We converted the comments system over to Disqus while the site was still running WordPress. This was done for a few reasons: Disqus comments provide one of the best experiences for the user, in my opinion. They also are platform agnostic, in that we could convert the whole site from WP to PW and not have to change a thing about the comments… no data conversion or importing necessary. Lastly, ProcessWire's built-in comments system is not quite as powerful as WordPress's yet, so I wanted cmscritic.com to get an upgrade in that area rather than anything else, and Disqus is definitely an upgrade from WP's comments. In order to ensure that Disqus could recognize the relations of comment threads to posts, we again made use of that $page->wpid variable that keeps the original WordPress ID, and also relates to the ID used by the Disqus comments. This is only for posts that originated in WordPress, as new posts use a ProcessWire-specific ID.1 point
-
It's my first post in this area and this barely validates as a "showcase case", but: I've finally managed to update my own Web presence, resulting in flamingruby.com. It's primarily a blog, but some of my projects are on display there too. This site has actually been up for months already -- wasn't going to post it here, but thought it'd be nice to prove that I've actually built something with PW after all.. Being responsive is fairly standard stuff these days. In this case no frameworks were involved, though; it's all hand-made, built from mobile first perspective and based on content alone, instead of predefined breakpoints. Some details I'm still not happy about, so it'll probably get tweaked every now and then, but at the moment things are pretty much in a stable state. Since it's a personal project, I've been slowly adding small tricks here and there, none of which really count as anything "special." One addition made just today, mostly as a proof-of-concept, is a combination of a simple module and new subdomain (static.flamingruby.com) to automatically serve assets from (at least in theory) cookie-free location. This is described in more detail here. For home page I built an importer module (with AngularJS GUI, which was actually quite fun) that periodically pulls content from various feeds.. a bit like what Nico did with his social timeline, but nowhere as cool as that. At the moment content is being pulled from GitHub (for which I had to put together MarkupLoadAtom) and Twitter (which kindly killed it's RSS support just in time, so I'm using rssitfor.me instead.. although that site interestingly spits out Atom and not RSS like one would expect.) That's just about it.1 point
-
This module generates a "stubs.php" file containing PHP-classes with documentation for the properties of each Template, based on it's fields - which means IDE support (auto-complete, inspections, documentation) for templates in modern IDEs that perform static analysis, such as PhpStorm. The output looks like this: <?php /** * Generated by TemplateStubs module 2013-04-13 15:29:33 * This file may be overwritten at any time. */ namespace tpl; use Page; /** * "basic-page" template * * @property string $title Title * @property string $headline Use this instead of the Title if a longer headline is needed than what you want to appear in navigation. * @property string $summary Summary * @property string $body Body Content * @property string $sidebar Sidebar * @property Pageimages|Pageimage[] $images Images */ class basicpage extends Page {} To use the generated documentation, start your template-file like this: <?php /** * @var tpl\basicpage $page */ Documentation and more details on this page: https://github.com/mindplay-dk/TemplateStubs You can consider this an alpha-release - I haven't tagged a release yet, and some details like template-class naming convention may change before I tag release 1.0.1 point
-
This thread is used as a place to collect: 1. links to posts in the forum answering (repeating) newbie questions 2. links to posts in the forum and elsewhere on the net giving good insight in processwire 3. links to good articles about processwire 4. links to good tutorials posted in the forum 5. links to movie clips 6. links to posts in the forum talking about modules 7. code snippets or links to code snippets 8. Usefull Helpfiles Many good posts that answers (repeating) newbie questions or give good insight in the how and why of processwire, links to tutorial posts, (also on the net), movie clips, clarifying articles and code snippets are spread over the forum. PM me if you know a link. About this kick start see this post: http://processwire.com/talk/topic/4143-wordpress-dominates-19-of-the-web/page-2#entry40910 This is a work in progress, it takes time to make it grow bigger and better. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = STARTING NEWBIES AND DESIGNERS Link1: Starting and growing with processwire. https://processwire.com/talk/topic/3990-another-simple-photo-gallery-tutorial/page-4#entry61069 Link2: I am basically a designer with some programming skills. My question is this: Can I go ahead to use processwire for this even though i am still learning php. http://processwire.com/talk/topic/3954-starting-out-with-website-intranet-and-internet/ Link3: Feeling overwhelmed http://processwire.com/talk/topic/3215-newbie-overwhelmed/ Link4: Questions concerning PW and it's capabilities http://processwire.com/talk/topic/1557-questions-concerning-pw-and-its-capabilities/ NEWBIES FIRST CODING QUESTIONS link1: Using a default install, I'm stepping through the tutorials, templates, etc and trying to understand the basic concepts behind processwire and at this point in time "head.inc" & "foot.inc". http://processwire.com/talk/topic/3421-footinc/ Link2: I am puzzled why some html tags are starting in head.inc but don't end in head.inc Instead they are ended in foot.inc http://processwire.com/talk/topic/3388-question-about-headinc-and-footerinc/ Link3: Question about not using ?> in processwire http://processwire.com/talk/topic/3370-question-about-missing/ Link4: After you installed processwire, it comes with a default website. What is the best way to fill in your own website ? How do you replace the default processwire website with your own ? http://processwire.com/talk/topic/3379-how-to-fill-in-your-own-website/ Link5:How much extra work/time will I have to put in, as far as understanding and writing php and getting the hang of the PW system, just to be able to create the same responsive designs I would make in HTML/CSS/Javascrip, while also achieving the easiest type of content editing capabilities (in line with what you can get with a CushyCMS type product)? http://processwire.com/talk/topic/3961-new-to-cms/ Link6: I realize what I am confused about was really something quite basic, such as where are the snippets of php code go beside on templates? Can they go on a page as the value of body field for example? http://processwire.com/talk/topic/3383-back-to-basic/ Link7: I'm stuck in something that should be very simple. http://processwire.com/talk/topic/3720-my-first-doubt-using-pw/ Link8: Several questions before I can start. http://processwire.com/talk/topic/3589-several-questions-before-i-can-start/ PROCESSWIRE CMS INSIGHTS Link1: Reading this thread makes you understand processwire real quick. http://processwire.com/talk/topic/5667-help-a-noob-get-started/ Link2: Very good case study from RayDale giving good insight in processwire http://processwire.c...a-a-case-study/ Link3: Symphony or Processwire ? Another good insight. http://getsymphony.com/discuss/thread/79645/ ARTICLES Link1: Why he choses processwire over modx http://www.mademyday.de/why-i-chose-processwire-over-modx.html COMING FROM MODX ? Link1: You've been using MODX but now you've found ProcessWire. It’s totally amazed you and you can’t wait to get started. But…you are wondering where everything is. If this is you, read on… http://processwire.c...ning-from-modx/ Link2: A MODX refugee: questions on features of ProcessWire http://processwire.com/talk/topic/3111-a-modx-refugee-questions-on-features-of-processwire/ Link3: Code comparison between modx and processwire. http://processwire.com/talk/topic/2850-processwire-for-designers/page-2#entry30349 COMING FROM DRUPAL ? Link1: How to move your site from Drupal to ProcessWire. http://processwire.c...ndpost__p__8988 PAGES IN PROCESSWIRE Link1: Understanding pages in processwire http://processwire.com/talk/topic/5667-help-a-noob-get-started/page-2#entry55820 Link2: More about the function of pages in processwire http://processwire.c...fused-by-pages/ Link3: How to hide Pages from the Topnavi via Adminmenu http://processwire.com/talk/topic/2037-how-to-hide-pages-from-the-topnavi-via-adminmenu/ TEMPLATES IN PROCESSWIRE Link1: A good post with code examples to start a template http://processwire.com/talk/topic/43-template-tutorial/ Link2: Template design a better route http://processwire.com/talk/topic/2782-template-design-better-route/ Link3: A different way of using templates http://processwire.com/talk/topic/740-a-different-way-of-using-templates-delegate-approach/ FRONT-END / BACK-END Link1: ProcessWire Setup and front-end editing made easy http://processwire.com/talk/topic/2382-processwire-setup-and-front-end-editing-made-easy/ Link2: Creating a front-end admin http://processwire.com/talk/topic/2937-creating-a-front-end-admin/ Link3: How would I build functionality and write information from the front-end to the back-end? http://processwire.com/talk/topic/2174-writing-from-front-end-to-back-end/ Link4: Is it possible to create a custom login page like a template ? http://processwire.com/talk/topic/107-custom-login/ Link5: A "members-only" section in the front-end. Integrating a member / visitor login form http://processwire.com/talk/topic/1716-integrating-a-member-visitor-login-form/ Link6: Trouble deleting pages from the front-end. http://processwire.com/talk/topic/2290-trouble-deleting-pages-from-the-frontend/ MODULE Front-end Edit. It turns the content of $page->body into a clickable area and gives the ability to frontend edit the content via tinyMCE http://processwire.com/talk/topic/3210-module-frontend-edit https://github.com/Luis85/PageInlineEdit/ MODULE Fredi, friendly frontend editing. http://processwire.com/talk/topic/3265-fredi-friendly-frontend-editing/?hl=fredi http://modules.processwire.com/modules/fredi/ MODULE Admin-bar Provides easy front-end admin bar for editing page content in ProcessWire 2.1+. http://processwire.com/talk/topic/44-is-there-way-to-get-information-about-current-user-in-templates/ http://processwire.com/talk/topic/50-adminbar/ http://modules.processwire.com/modules/admin-bar/ MULTI LANGUAGE WEBSITE IN PROCESSWIRE Link1: Multi-language website page names / URLs http://processwire.com/talk/topic/2979-multi-language-page-names-urls/ Link2: API http://processwire.com/api/multi-language-support/multi-language-urls/ Link3: The name of the default language can't be changed in Pw, but the title. http://processwire.com/talk/topic/4145-recoverable-fatal-error/#entry40611 ADD NEW USER TO YOUR WEBSITE AND PASSWORD RESET Link1: Integrating a member / visitor login form http://processwire.com/talk/topic/1716-integrating-a-member-visitor-login-form/?hl=%2Bpassword+%2Breset#entry15894 Module http://processwire.com/talk/topic/2145-module-send-user-credentials/?hl=%2Bpassword+%2Breset BASIC TUTORIALS FOR NEWBIES Link1: Approaches to categorising site content http://processwire.com/talk/topic/3579-tutorial-approaches-to-categorising-site-content/ CODE SNIPPETS AND FUNCTIONS Link1: Get page id from images object https://processwire.com/talk/topic/6176-get-page-id-from-images-object/ Link2: Function to render Bootstrap 3 carousel markup from ProcessWire images object https://gist.github.com/gebeer/11200288 .HTACCESS EXAMPLES ON YOUR HOSTING SERVER Example1: A working .htaccess file. The issues were that the .htaccess file must exist on the server before installing processwire and that the server did not allow options in the .htaccess file. After fixing that processwire could be installed on the server without any problem. Note that such restrictions might be different on your server that you need to find in the faq of your host. RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA,NC] HTML KICKSTARTER Link1: How can i integrate HTML Kickstarter with processwire? http://processwire.com/talk/topic/2731-how-can-i-integrate-html-kickstarter-with-processwire/ MOVIE CLIPS Field dependencies are coming in ProcessWire 2.4. Field dependencies are basically just a way of saying that one field depends on another. It dictates which fields should be shown in a given context. https://www.youtube.com/watch?feature=player_embedded&v=hqLs9YNYKMM HELP FILES Cheatsheet Link1 Cheatsheet 1.1 as pdf file Download: http://processwire.com/talk/index.php?app=core&module=attach§ion=attach&attach_id=1299 Link2 Cheatsheet is now a processwire site (great work by Soma) http://cheatsheet.processwire.com/pages/built-in-methods-reference/pages-find-selector/ INTERVIEWS Link1: About the history and coming to be of processwire http://processwire.com/talk/topic/4084-about-ryan-and-processwire-an-interview-with-ryan-cramer/1 point
-
Hello guys, Iam Jan a web/graphic designer from germany. For the last 2 weeks I was searching for a great cms soulution for small to medium-sized companies. My customers are artist, photographers, small agencys or startups. I really like the way PW works, because it seems like I can design everything and dont have to force the design in the system. I can write HTML/CSS and can implement JQuery as I would do on a static website, than I can make it dynamic using PW. Still there is one thing I struggle with, and thats to lern PHP. Iam by no means a programmer and I will never be one. I can see me learning the basics but would like to write PHP code as little as possible. I have tryed Wordpress for a small website and while I think PW is a much better/cleaner solution, I do like how it handels themes, plugins and backend UI. For me the plugins can really save me some time in using functions, that I would never be able to implement on my own or with a lot of work. To reach the Wordpress audience, there are some things that need to work better in PW in my opinion. -Easy export/import of themes/profiles without using modules -Showcase of themes/profiles on the PW site -HTML framework integration (e.g. Bootstrap, Kickstart, 960grid) and showcase on the website. -A simple Blog module. I know there is the Blog Profile but it seams a little to complicatet for me. -A gallery module with JQery integration. That would be great for the not so tech savvy design guys like me and other WP users. -Also a starter Tutorial on the Website (not the Forum) or a tutorial section would be cool, as some tutorials can be hard to find for a newbie. -The button view in the backend when you hover a page is not nessesary in my opninion as you can view it unsing the button on the top when you in edit mode. The first Option here should be edit, as thats would a normal user would do in most cases. Anyway I realy like PW and looking forward to use it on future project. Thanks for reading Jan1 point
-
Good day all! I'm looking to hire a programmer to further build out the Email Image module (http://modules.processwire.com/modules/email-image/). I'd like to build upon or modify this plugin to meet my needs. That being said, I am very open to sponsoring this and releasing it to the public as a free module (add-on to the current module or a new one), however it makes the most sense. What I'm looking to accomplish: 1. The text of the email creates a new blog/page entry in a specific category/section. 2. Images (email attachments) upload to the new blog/page entry and inserts into the page below text in grid layout. Images would enlarge with light box treatment or something similar. Descriptions for each individual picture could be edited in PW at a later time. 3. Needs further investigation - option to convert attachments to slider gallery. Basically, this would be a field report that someone would email to create a new entry with pictures underneath. Timeframe: 30 days Budget: Approximately $500USD (please let me know if this is way off base) Payment Method: Paypal, Credit Card, Bank Transfer (international bank transfer possible but I have not done this before with my current bank, so would have to investigate further) Thanks, Jason1 point
-
Ok, if you are setting up a page tree of front-end page authors (that are not PW admin users), then I would suggest a page tree like: Authors (template: authors) --John Smith (template: author) --Mary Brown (template: author) The author template could have your portrait image field for each author along with other details about them. Not sure how they are authoring these pages, but presumably through a front end form? As the author creates the page, just assign their ID to the page in an author field. To delete an author and have all their pages deleted could be done easily through the API by using a selector to grab the array of pages with the appropriate author and foreach'ing through, deleting each one. This very rough idea would set all the pages with the assigned author to unpublished. If you want you could obviously delete instead. foreach($pages->find("author=ID") as $selected_page){ $selected_page->addStatus(Page::statusUnpublished); } You might want to do this through the admin by setting up a special page. You could create a simple module, or make use of diogo's http://modules.processwire.com/modules/process-admin-custom-pages/ module - it is really cool for things like this.1 point
-
Simply PM me the links and I will add, categorize them and give them a description.1 point
-
Maybe you are referring to avatar type images for admin users? In that case, you can add an images field to the user template. It might be best to limit it to one image, so it that case you would want a new image field as the one that comes with the default profile allows multiple images. Are either of us on the right track with your question?1 point
-
Personally I don't have an issue with current documentation, but I very rarely use it either -- cheatsheet is awesome and if something seems confusing I prefer to check it from source. This is why I'm wrong person to talk about the state of current documentation, but still: I don't think anyone here really has an issue with improving documentation *as long as it doesn't undermine it's current state of simplicity*, which seems to work very well for some folks out there. One issue is that in order to write better documentation people writing it need feedback, tips on what to improve and (optimally) even pointers to how that should happen. I'm seeing some concrete tips in what @Zahari wrote up there. Posts like that provide valuable information. One problem I'm seeing quite often these days are so-called "newbie questions" that have already been answered (usually multiple times) here on the forum.. or are *very clearly* answered within the docs. I'm not trying to discourage those who want to ask, I'm just worried since this obviously isn't optimal situation for anyone: the forum itself is great source of information, but people don't seem to find that information well enough. Have you seen @kongondos replies and how there are often bunch of links to similar threads in the end..? One problem might be that people don't do Google searches ("site:processwire.com categories" etc.) often enough. <voice type="semi-sarcastic">Perhaps what we really need is a how-to guide for finding stuff here.. and it needs to start with either "don't panic" or "forget forum search, Google it!" </voice> Sounds good and that's exactly what the wiki is for. It had an awesome start but now it's a bit quiet. If you'd fancy working for it, I'd suggest contacting Ryan (I think it needs registration, which doesn't seem to be open.)1 point
-
1 point
-
Hi Manol, assuming you build a login page (frontend) in PW and ask for username and pass. Send it with your script to custom intranet DB, if result is true (valid user) you now can check if user already exists in PW, and if yes, select him. $users->setCurrentUser($users->get('username')); otherwise you can create him via API. I would handle all stuff in that login page.1 point
-
I can't edit the name of members I will add a custom role, like you said and change the assigned role on Mysql, if possible. But the users login is working, yet you need to reset the password. Thank you SiNNuT 2 SiNNuT Module Based on Geoip Google maps used on site Ryan's profile skyscrapers: http://modules.processwire.com/modules/fieldtype-map-marker/ p.s. oh well I was writing this and kongondo wisdom and detective work beats my newbie pWire skills for sure. ^ yes I read it now eheh ^1 point
-
Have a read at this earlier post on page #4 of this thread. It talks about roles. Seems you can import roles actually. http://processwire.com/talk/topic/383-module-import-pages-from-csv-file/?p=101601 point
-
Quickest I can think (without much thought )... You can output the p->url conditionally, i.e. something like if ($p->title == "settings") { //href='output link to edit the page' } else { href='{$p->url}'//example, snipped code... } Maybe even assign href value to some variable. This is probably quick and dirty and there could be a better way. Untested and it is just an idea.. Now, very important. Do not edit /wire/templates-admin/topnac.inc. Instead, copy the templates-admin to your site folder. That way, PW will instead serve your site templates-admin instead of the wire one. It will also survive an upgrade... Edit: Corrected code1 point
-
HI joey. Welcome to PW and the forums! A quick one, that's because the code generating that menu at the top outuputs those pages URLs. So clicking on setup, renders setup. Clicking on access renders that...hence, clicking on your "setttings" renders that... This is the line outputting the URLs in the file topnav.inc, specifically the $p->url echo "\n\t\t\t\t<li><a href='{$p->url}'$class>$title</a></li>";1 point
-
Yep, I think $page->save() is what is missing. Soma, yep, $page->product_comments->averageRating comes from my customized module.1 point
-
What you mean with no dice. It's not about luck or dices What you expect to do it? Is average_rating a field? Where is averageRating coming from? And don't you need to save the page or field after setting it?1 point
-
I just uploaded a new version with logging and a fix for the issue Ryan described. @ceberlin and Pete I hope you can install this version this version with logging enabled (logging can be enabled in the module configuration). Every automatic (un)publication will be logged in the /assets/logs/messages.txt file, with timestamps for the publish_from and publish_until fields and the timestamp of the event itself. If the problem still exists, we can take a look at the logfile. /Jasper1 point
-
If you want more control over your images trown in with WYSIWYG. And you want captions for landscape or/and portrait or both. Maybe you can take a look at TextformatterImageInterceptor. The text formatter will recognize image orientation. (also recognize image tags if tagged sets are used) If you wish, add a class for the caption div and the caption wil be created underneath the image with the classname you specified. So basicly you have image caption control over different kind of images. There are other settings like cropping, sizing, positioning and wrapping images. Will not cover the details here. And maybe there's to much overhead ( server side ) using my module for just captions. about the textformatter: forum post <blink>advertisement</blink>1 point
-
I believe these types of articles only serve as a distraction. They are popular and get a lot of press. Even if Wordpress had 99% of the webpages it doesn't make it a better product than ProcessWire. I have used Wordpress and Joomla for customer sites, in the past. They were a tool that got the job done, then, because I wasn't aware/knowledgeable of better tools. Since, I have discovered ProcessWire, I now know that those tools aren't appropriate for seriously developing websites or web applications. They have great strengths but also many technical weaknesses. Anyone who seriously compares Wordpress, Joomla or Drupal to ProcessWire and then states that technically those 3 are better, is not dealing with reality. I could spend the next year learning about all the remarkable things you can do with ProcessWire. I now believe the only limitation is your imagination.1 point
-
Just a quick note to those trying unsuccessfully to login via Twitter the past few weeks - this is finally fixed now and you can carry on as usual.1 point
-
Yep, this is great module. I also want to encourage people to write their own import scripts. It is simpler than you can believe and you can re-import easily.1 point
-
Went yesterday to the cinema to see "Drupal & Joomla 6", and was not disappointed. Highly recommended!1 point
-
This module is now complete: http://processwire.com/talk/topic/3743-processemailtopage/ Thanks to Jason for allowing it to be released to the community1 point
-
I'd be interested in taking this one on. Timeframe is more than enough, changes required to the module aren't that tricky either. I don't think you're wanting to do this, but you could assign a different email address to a different section of the site or something if you wanted to handle different blog categories, or else something could be done with category title as part of the email title like "Post title||categoryname" and split on the || Lots and lots of possibilities.1 point
-
There's an example on that page you linked... Let's look, to have PW pagination module work you need to use some search $pages->find() ..children() ..siblings() with a limit selector as explained above. But this alone isn't going to cut it. You'll also need to render the pager. This, you do by using the result you get from the find() and add a renderPager() to it. So the above code is missing that. Let's add the missing part. <?php if($page->numChildren) { $result = $page->children("limit=2"); // render the pager echo $result->renderPager(); // render the children echo "<ul class='nav'>"; foreach($result as $child) { echo "<li><a href='{$child->url}'>{$child->title}</a></li>"; } echo "</ul>"; // render pager again? ok echo $result->renderPager(); } Wasn't that easy?1 point
-
In 2.3, there are also these two additions (so far, undocumented). Either one returns the number of visible children: $page->numChildren(true); $page->numVisibleChildren; I will be adding these to the API pages, along with all the other 2.3 additions very soon.1 point
-
hi, same here: my profession is designer and copwriter, not coder. i still have difficulties to think like "real" coders but i'm progressing. however, here is what i found after having discovered pw for me (i came from contao via textpattern to pw and i have some good knowledge of wp too): coding is fun coding with pw is even more fun because it rewards you with success pw gives me the superpower i always wanted when i tried to adapt contao's pre-made markup to my needs you would like to do the same with wp you can do with pw? good luck - go and learn advanced php. beginner skills will not be enough apart from this, i'm not sure if making wp themes is a good business. if i look at themegarden for example it seems quite competitive. why not specialize in custom tailored websites to clients that appreciate it? from my experience, this market is competitive too, but working. enjoy pw!1 point
-
1 point
-
WillyC is right! How could I missed it So you can do: $form->setMarkup(array( 'list' => "<div {attrs}>{out}</div>", 'item' => "<div {attrs}>{out}</div>" ));1 point
-
[quotamos]This is really interesting stuff and I'm learning so much from it. I've already tested Soma's code and it works very well. Is there a way of configuring $form->render() so that it outputs different html (divs for ul/li etc.)? [/quotamos] you.can usage. $form->setMarkup(); und $form->setClasses(); two.set markups und html caresses. see.eliamos /wire/core/InputfieldWrapper.php1 point
-
Great tutorial Soma! This is the best summary of using PW's Inputfields that I've seen. I noticed you did $field->attr('id+name', 'email') so just wanted to explain what that is for those that may be unsure of the syntax. That syntax is basically saying to set the 'id' and 'name' attribute to have the 'email'. While every field needs a 'name' attribute (like in HTML) the 'id' attribute is optional… if you don't assign an id attribute, PW will make one up. If you intend to custom style a field with CSS or target it from javascript, then it's best to assign your own 'id' attribute. Otherwise, it doesn't matter. // this… $field->attr('id+name', 'email'); // …is the same as: $field->attr('id', 'email'); $field->attr('name', 'email'); // …as is this (direct reference): $field->id = 'email'; $field->name = 'email'; The advantage of using the attr() function over direct reference is that attr() can't ever collide with other Inputfield properties that might have the same name as a field attribute. It's basically your way of saying "this should definitely be an HTML attribute and not anything else." For recognized attributes like 'name' or 'value' it doesn't matter what syntax you use because an Inputfield already knows 'name' and 'value' are standard HTML attributes. But if you needed to add a custom attribute like "data-something", well then you'd definitely want to use the attr() method of setting. That attr() method should only be used for things that would actually be HTML attributes of the <input>, because they will literally end up there. So if you do an $field->attr('label', 'Hello'); you'll end up with an <input label='Hello'> in the markup, which is obviously not something that you want. That's why you assign a non-attribute property like 'label' or 'description' directly, like: $field->label = 'Something'; Last note about $attr() is that it can be used for both setting and getting attributes: $field->attr('value', 'something'); echo "The field's value is: " . $field->attr('value'); // same as: $field->value = 'something'; echo "The field's value is $field->value"; To extend your example, lets say that you wanted the 'email' and 'password' fields in a fieldset titled "About You". You would create the fieldset, and then add/append the fields to the $fieldset rather than the $form. Then you'd add the $fieldset to the $form: $fieldset = $modules->get('InputfieldFieldset'); $fieldset->label = 'About You'; $field = $modules->get("InputfieldEmail"); $field->label = "E-Mail"; $field->attr('id+name','email'); $field->required = 1; $fieldset->append($field); // append the field $field = $modules->get("InputfieldPassword"); $field->label = "Password"; $field->attr("id+name","pass"); $field->required = 1; $fieldset->append($field); $form->append($fieldset); Or lets say that you wanted those 'email' and 'password' fields to be each in their own column so that are next to each other horizontally rather than vertically. You would assign the 'columnWidth' property to both the email and password fields. In this case, we'd give them both a value of 50 to say that we want them to be a 50% width column: $field->columnWidth = 50; To jump out of tutorial mode and into idea mode: lately I've been thinking that PW should have a YAML to Inputfields conversion tool in the core (something that would be pretty easy to build), so that one could define a form like this: And create it like this (where $yaml is the string above above): $form = $modules->get('InputfieldForm'); $form->load($yaml); echo $form->render();1 point
-
I like this because it was already what I was doing The closing PHP tag is something I've picked up from coding with PW.1 point
-
PW's coding style is visible in any core file. But it's the same idea whether we're talking about code, graphic design, architecture or really anything someone would create: When it comes to code, that translates mostly to not adding extra unnecessary bytes: Avoid having an opening bracket "{" on its own line. Instead, just use a single space before an opening bracket. Only closing brackets "}" should be on their own line. Avoid use spaces for indentation, just tabs. This is what tabs were made for, not spaces. Use just one tab per indentation, of course. Avoid extra spaces around parenthesis unless you think it's really necessary. For example, it's preferable to use function(a, b) not function ( a, b ) Put a space after a comma, just so the comma doesn't visually melt into one of the adjacent letters. Don't put a closing PHP tag "?>" at the end of a file. Use camelCase for most variable and function names except for when the variable resolves to a database column or ProcessWire 'name', then use lowercase and underscores. Use camelCase for class names except always have the first character be uppercase, i.e 'CamelCase' (there may be a more specific term for this). Put a space before and after the concatenation operator, as it's small and disappears (or becomes a sentence period) too easily. For example use "a . b" and not "a.b". And of course, comment as much as possible. Comments are bytes that are always appreciated for communication. Outside of internal comments within the body of functions/methods, PHPdoc style is the standard we prefer. Honestly the biggest one for me is just the opening bracket thing. I can't follow code that contains opening brackets on their own line. It makes the opens and closes so visually similar that I can't can't easily tell them apart. It could be that my eyes aren't great, but at least for me that coding style creates legibility problems. I have to "fix" code before I can read it. With the style I'm using, when I see a bracket on a line (before I see the nuances of the serifs), at least I know it is always closing something.1 point