Leaderboard
Popular Content
Showing content with the highest reputation on 08/10/2013 in all areas
-
3 points
-
To be consistent it's probably best to use PW's own sanitizer for pageName: $sanitizer->pageName($value, true) See the cheatsheet http://cheatsheet.processwire.com/#sanitizer and/or look at the source if you want to check out what it does exactly https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/core/Sanitizer.php3 points
-
The output of a template is ran through the PHP function trim(), which removes whitespace characters surrounding strings (start and end). \n is one of those characters.3 points
-
Just recently came across this neat jQuery sorting and filtering plugin. I haven't used it myself but it seems easy enough to implement. Thought i'd share. http://mixitup.io/ one of the demos: http://mixitup.io/demos/parks2 points
-
2 points
-
The creation process really isn't a problem with the tools Ryan mentioned. Especially for stuff like country lists i think it's really powerful to use pages. Easy to maintain; if a country name changes (yes, this does happen every once in a while) you just update that page and everything using it will always be in sync, be it your select options or other places you used the country pages. Maybe you would want to add some additional info, like a country flag or multilingual country names. This stuff all becomes easy and transparent if you use pages. What if later on you would also want to support regions and/or continents? Easy to implement when everything is pages.2 points
-
For completeness I would like to add the final code I came up with. I decided to not only set the value of the title field, but also the value of the name field (called _pw_page_name internally). This is because the page name gets entered automatically as you type into the title field, but stays blank if the value of the title field is preset, thus causing an error when the page is saved. class FieldHelper extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( 'title' => 'FieldHelper', 'version' => 100, 'summary' => 'Hide fields depending on permission, role, or user.', 'singular' => true, 'autoload' => true ); } public function init() { // add before-hook to the inputfield render method $this->addHooKBefore("Inputfield::render", $this, "renderField"); } /** * Pre-fill certain fields if empty with unique identifier based on the page id * */ public function renderField(HookEvent $event) { // Get hold of an instance of the parent $parent_id = wire('input')->get->parent_id; $parent = wire('pages')->get($parent_id); $field = $event->object; $name = $field->name; $value = $field->value; // Only prefill the title field // for children of pages with template 'customer': if ($parent->template == 'customer') { if ($name == 'title' || $name == '_pw_page_name') { if ($value == '') { $presetValue = $this->uniqueValue(); if ($name == '_pw_page_name') { // URL-encode path name // http://php.net/manual/en/function.filter-var.php $presetValue = filter_var($presetValue, FILTER_SANITIZE_URL); } $field->set('value', $presetValue); } } } } public function uniqueValue() { $last_page_id = wire('pages')->get("include=all,sort=-id")->id; $id = date("Y") . "/" . ($last_page_id+1); // example for a possible id value return $id; } } Output in the admin on opening a new page: Title: 2013/1073 Name: 2013-1073 I am not sure if using filter_var($presetValue, FILTER_SANITIZE_URL) is the best way to sanitize the URL path name. Please let me know if there is a better or more idiomatic way. Cheers, Stefan2 points
-
Soma, since you pointed me to it specifically, I just wanted to let you know that I was able to use ImagesManager for my project and it fit the bill completely. Thanks for taking the time to work on image gallery management for PW!2 points
-
Every time I use this module I laugh when it's complete. I just imported 200+ pages flawlessly — Beer:30.2 points
-
We'll use this thread to discuss PW 2.3 features as they are being worked on. I've just added one of the first components. This is the "Page Path History" module. It's now in the PW core as a beta module (uninstalled by default). If you are interested in helping to test, just install the module from Admin > Modules > Page > Page Path History (after doing 'Check for new Modules'). The Page Path History module keeps track of the previous URLs for any pages that have been moved or renamed. It then sets up automatic redirects (301, permanent) to ensure the old URLs redirect to the new ones. This is best demonstrated by a few examples: Lets say you had the page /about/contact/ and you moved it to /contact/. With the Page Path History module installed, anyone accessing /about/contact/ will get redirected to /contact/. You had a page called /our-products/ and you renamed it to be /products/. Any accesses to /our-products/ will now get redirected to /products/. Those are simple examples, but this module can handle more complex situations too: Lets say you had the page /our-products/furniture/whoopie-cushion/ and you did like in the previous example and renamed /our-products/ to be /products/. The /our-products/furniture/whoopie-cushion/ URL will now redirect to /products/furniture/whoopie-cushion/ Later on you decide to rename /products/ to just /inventory/. All the /our-products/ and /products/ URLs will continue to work with redirects. You decide that whoopie-cushion really belongs in /services/ rather than /inventory/, so you drag it to /services/whoopie-cushion/. It's old URL in /inventory/furniture/whoopie-cushion/ redirects to it's new URL. TL;DR (am I doing this right) -- you can move or rename any pages and all the old URLs will redirect to the new, automated behind the scenes, without any thinking on your part.1 point
-
Lets see if we can get a quick-start tutorial going here. We'll start with something really simple and then work up from there. Tell me when something makes sense and when it doesn't and we'll adjust as we go. My thought is that we'd make a tutorial that plays on the 'hello world' phrase and lists information about planets in the solar system, starting with Earth. To keep it simple, we'll assume that the basic site profile is installed, as that's what comes with ProcessWire (so there's no need to uninstall anything). But we won't start using any of it's files tat this stage. Instead, we'll start out by creating our own files. STEP 1 – Create a template file Create a new file called: /site/templates/planet.php, and copy+paste the following HTML into that file: <html> <head> <title>Earth</title> </head> <body> <h1>Earth</h1> <h2>Type: Happy planet, Age: Millions of years</h2> <p>Earth (or the Earth) is the third planet from the Sun, and the densest and fifth-largest of the eight planets in the Solar System. It is also the largest of the Solar System's four terrestrial planets. It is sometimes referred to as the World, the Blue Planet, or by its Latin name, Terra.</p> </body> </html> The above is just a plain HTML file with nothing specific to ProcessWire. We will use this as the starting point for our template, and we'll go back and modify it later. STEP 2 – Add a template to ProcessWire Login to ProcessWire admin and go to Setup > Templates. This page shows a list of templates currently in the system. Click the Add New Template button. On the next screen that appears, you'll see it found your "planet" template file. Check the box next to the planet template and click Add Template. You may ignore any other options that appear on this screen. STEP 3 – Creating a page using your template Your planet template is now in the system and ready to use, but it's not being used by any pages. So lets create a page that uses the planet template. In the ProcessWire admin, click Pages in the top navigation. This is a site map if your page structure. We want to create a new page under the homepage, so click the new link that appears to the right of the home page. The next screen has 3 inputs: title, name and template. Enter "Earth" for the title, and the name should populate automatically. For the template, select planet. Then click Save. Now you have created a new page using the template that you added. You are now in the page edit screen and you should see your title field populated with "Earth". Click the View link that appears on this page edit screen. You should see the output of the HTML from step 1. Click the back button in your browser to return to the edit screen. STEP 4 – Creating a new field Now you know how to create a template and a page using that template. You could create more pages using the same template if you wanted to. But that wouldn't be particularly useful – this template file is just a static HTML file. Lets make it dynamic by creating some fields and adding them to it. We are going to create 3 fields to represent the pieces of data that currently appear in our static template. These include the planet's type, age in years, and a brief summary. We will call these fields: planet_type, planet_age and planet_summary. In ProcessWire admin, click Setup > Fields. This screen shows a list of fields currently in the system, most of which are general purpose fields for the basic profile. For the purposes of this tutorial, we are going to ignore those and create our own. Click the Add New Field button. On the next screen, enter "planet_type" for the Name, select "text" as the Type, and enter "Planet Type" for the Label. Then click the Save Field button. Now that your field is saved, you are on the Field Edit screen. At this point, your field is created and ready to be added to your planet template. Optional: While editing your field, click the details tab where you'll see a select box for Text Formatters. Select "HTML Entity Encoder" – this ensures that characters like "<", ">" and "&" will be converted to HTML entities and not confused as HTML tags. While not required, it's a good practice for text fields like this. After you've done that, click the Save Field button. STEP 5 – Creating more new fields In step 4 we created the planet_type field. Now we want to create the planet_age and planet_summary fields. So in this step, you'll want to do the same thing for the remaining two fields: Create the planet_age field exactly like you created the planet_type field, but enter "Planet age in years" for the label. Create the planet_summary field exactly like you created the planet_type field, but chose "textarea" as the Type and enter "Planet summary" for the label. Note that a "textarea" field is just like a "text" field, except that it can contain multiple lines of text. STEP 6 – Adding new fields to your template Now that you've created 3 new fields, you need to add them to your planet template. In ProcessWire admin, click Setup > Templates > planet. You are now editing your planet template. In the Fields select box, choose planet_type, then planet_age, then planet_summary. You will see each added to the list. Cick the Save Template button. STEP 7 – Editing a page using your template Now that you have new fields added to your template, go back and edit the Earth page you created earlier and populate the new fields that are on it. In ProcessWire admin, click Pages at the top, then click the Earth page, and click the edit button that appears to the right of it. You are now editing the Earth page you created earlier. You should see the new fields you added, waiting for text. Enter "Terrestrial planet" for Planet Type Enter "4.54 billion" for Planet Age in Years Paste in the text below for Planet Summary and then click Save. STEP 8 – Outputting dynamic data in your template file While still in the page editor from step 7, click the "View" link to see your page. Note that it still says "Happy planet" for type (rather than "Terrestrial planet") and "Millions of years" rather than "4.54 billion years". That's because the page is still being rendered with just the static data in it. We need to update the template file so that it recognizes the fields we added and outputs the values of those fields. Edit /site/templates/planet.php and replace the static text in there with tags like this, replacing field_name with the name of the field: <?php echo $page->field_name; ?> If supported by your server, you may also use this shorter format which some people find easier to look at and faster to enter: <?=$page->field_name?> Here is the /site/templates/planet.php file updated to output the content of the page using tags like the above: <html> <head> <title><?php echo $page->title; ?></title> </head> <body> <h1><?php echo $page->title; ?></h1> <h2>Type: <?php echo $page->planet_type; ?>, Age: <?php echo $page->planet_age; ?> years</h2> <p><?php echo $page->planet_summary; ?></p> </body> </html> After making these changes, save your planet.php template file. Now view your Earth page again. You should see it properly outputting all of the content you entered on the page, including "Terrestrial planet" for Type and "4.54 billion years" for age. Any changes you make from this point forward should be reflected in the output. STEP 9 – Creating more pages, reusing your template For this last step, we'll create another page (for Jupiter) using the same template just to demonstrate how a template may be reused. In ProcessWire Admin, click Pages and then click the new link to the right of the home page. Enter "Jupiter" as the Title and select "planet" for the Template. Click Save. Now that you are editing the Jupiter page, enter "Gas giant" for Type, enter "4.5 billion" for Age in Years, and copy+paste the following for Planet Summary: Click the Publish button and then View the page. You should now see your planet template being used to output the information for Jupiter rather than Earth. CONCLUSION In the above, we covered the basics of how to develop in ProcessWire, including the following: Creating templates and their associated template files Creating basic text fields and adding them to templates Creating and editing pages that use your templates Outputting the values of fields in template files If all of this makes sense so far, I thought we'd follow up next with a tutorial to take this further: Adding and outputting photos for each planet Creating navigation that lists all the other planets that have pages in the system …and we'd keep building upon the tutorial from there. If you all think this tutorial is helpful, then perhaps this can be a draft for a real tutorial we'll put on the site, so all of your help is appreciated in making this as good as it can be.1 point
-
01. & 02. It's /site/templates/ ( the place where to put the MarkupCSScompress.php, it's just a PW template ) 03. CSS files have to be PW accessible. ( CSS files from other sources won't work, other domains for example.) 04. The order is the order that files are in the array. 05. The module here is triggered, and uses the MarkupCSScompress.php (template) to output the combined styles.1 point
-
1 point
-
It certainly doesn't hurt and is good practice, but you don't really need to sanitize it at all - you are defining exactly what it will be yourself. The one thing to note on this is that PW is automatically converting the "/" in between the year and the page id, into a dash for the name field. You could do this yourself, which $sanitizer->pageName would take care of. The one thing you might want to sanitize is $parent_id by using "(int)", eg: $parent = wire('pages')->get((int)$parent_id); which converts it to an integer, making that pages->get completely safe. Probably unnecessary since this is an admin form, but that original get variable could be changed by someone.1 point
-
This is why I always configure the settings on the "family" tab of each template before delivery, at least for sites that will ultimately be managed by a client. Presumably these same settings would be applicable for a Fieldtype/Inputfield module that pursues this multi-template repeater strategy. This was always one of my concerns with repeaters in the first place. It might be a bigger concern with a multi-template repeater. I don't see 1-screen page editors as something that should be scalable like this, at least not too far in quantity. Whereas the page tree is, and should be. Though at some point I would like to introduce pagination into repeaters for the admin UI, but a little worried that might encourage more bad repeater behavior. I do like repeaters, but it does seem like they get used for more things than they should, at least based on questions that have sometimes popped up in the forums. They introduce ambiguity into how to solve a particular problem. Before repeaters, it was always easy to answer how to solve any problem: use pages. After repeaters, the answers aren't as easy. Though for the places that repeaters are the right answer, they are a nice time saver. But I rarely find a use for them in my own projects. Shifting gears back to append ideas to my previous message, and maybe thinking of something different: one idea could be to have a checkbox on each template that says "Children tab shows: 1) links to child pages; 2) editors to child pages". If they select "2" then the children tab would show those iframe editors to each child page in a repeater-like format, and an add button, like mentioned in my previous post. It would show that rather than a PageList. An option for pagination would be a must have though.1 point
-
Whether repeater or not, this sounds just like the solution we've been missing. I'm always worried about giving editors too much freedom, as I've seen how that often leads into bloated sites with very little structure (and eventually it's all so messed up that starting over from scratch is only solution), but by maintaining the control of what can be inserted and where this sounds like a very good compromise between giving the user enough freedom while still not letting her create a mess. Just for the record: I'm not too interested in small "campaign style" sites consisting of couple of pages, where any kind of mess is still controllable. Sites I'm worried about are those with hundreds, thousands, or even tens of thousands of pages. That's when things can very easily get out of control unless proper constraints are in place. PS. Reading that post made me spill coffee all over my laptop. Not sure if that's a sign of me being totally excited about this or simply a reminder to avoid any and all activities requiring hand-eye coordination before actually having that first cup of morning coffee.1 point
-
I think this type of thing would be a very different animal from a repeater. While there are similarities, I think the functionality would be a lot simpler to build as its own thing rather than extending repeaters. Not to mention, I'm not sure I'd want to add that complexity to repeaters either. I can't envision a use for this type of field in the sites that I build for my clients, so I'm not likely to build it. But I can see how others would find it useful, I do agree that the idea is fun and interesting. Here's how I think it could be built without getting too complex: The Fieldtype itself would basically just be a FieldtypePage and may not need to be anything more. The Inputfield would be where all the action would happen, and I think a lot of it would be JS fun more than PHP code. When you click "add", the Javascript would append an <iframe> with a "src" attribute pointing to /processwire/page/add/?parent_id=123&modal=1 where "123" represents the predefined parent_id where these pages would go. That "modal=1" in there tells PW's admin to just display the editor and no header/footer, etc., making it perfect for this particular Inputfield. The "add" screen would prompt them for the template, as it already does, and let them add the page there. You could of course restrict the allowed the templates the usual way in the template family settings. Some JS would also have to be used to communicate between the <iframes>s and the parent window. Specifically, when the Save button is pressed in the parent window, you'd have JS trigger the save buttons in the other iframes (which you might choose to hide with JS/CSS). Likewise, JS would need to be used from the parent frame to examine the ID of the iframe/repeater items so that it could be saved to the FieldtypePage. There wouldn't be any need to add new API level stuff, because I think that what's provided by FieldtypePage already provides what this field would need. There would be some other issues to resolve as well, but ultimately the whole thing would be simpler to build than the repeaters if the author is willing to take advantage of iframes.1 point
-
Thanks Ryan - after hours of trying to figure out what I was missing in access control it turns out to be something I wouldn't have thought about or noticed until it was working and I tried to link back. So I guess it makes sense for RSS that you would need to have a template to be viewable. Works as expected now.1 point
-
This functionality would be very much like Advanced Custom Fields "Flexible Content" Addon (http://www.advancedcustomfields.com/add-ons/flexible-content-field/). Which is probably at this point the only thing I miss about building WordPress sites. I found that clients found it easy to use and I didn't have issues with clients making a huge mess. It is a controlled system so testing for issues is quite easy.1 point
-
I pushed an update to the dev branch yesterday that should solve the issue of broken links in textarea/HTML fields when migrating a site between a subdirectory and root, and any other scenario that involves a change to the site's root path. This was previously solved by the the PageLinkAbstractor module, but I've always been on the hunt for a solid core solution. The solution I put in is really basic and simple, and I'm not 100% positive it's the right one, but here's what it does. When editing the settings for any Textarea field, you now have a "Content Type" setting: If you select "Markup/HTML" then it signals FieldtypeTextarea to look for certain attributes to convert when you save the page. Specifically, it's going to convert any local pointing <img src='...'> or <a href='...'> attributes to assume that the site's root is always "/" (at least from a DB storage perspective). Then whenever the field is loaded, it converts them back to the site's actual root. Using this method, any links or images placed in your TinyMCE/CKEditor textarea fields should continue working normally no matter where you move your site. Like PageLinkAbstractor, it doesn't retroactively apply to existing links. It only applies to links/images saved on pages after enabling the option. Unlike PageLinkAbstractor, it keeps the original code in a state that's still portable regardless of whether you later turn off the option or pull the text directly out of ProcessWire's DB. It's not yet had a lot of testing yet, so don't choose "Markup/HTML" unless you want to test it. As of 10 minutes ago, it's now compatible with TextareaLanguage as well.1 point
-
Yes, you call it from within a method / function == wrong scope! You need to call it wire('input')->get->parent_id, I think.1 point
-
Interesting...if there's interest in this and someone doesn't show us why this would not work, maybe we can start a new topic to discuss this? Just flesh out ideas, discuss drawbacks, advantages etc. This could become a non-core module. I'm getting ahead of myself though and haven't thought this through (e.g. searching the repeaters, memory resources, etc.)1 point
-
Being able to compose a page of individual blocks on the fly has been requested a couple of times now. I remember asking for something similar some time ago (click). I think the obvious and most comfortable solution would be that repeaters have no fields attached to them but rather templates, or only one template to have the same functionality as we have now. One step further would be that one is able to attach more than one template to the repeater, and then while creating content when you click add item a drop down appears with the template names you added. You choose a template and the next repeater item contains the fields of that chosen template. Next item could be another template and so on. This would be awesome. I would create this kind of behaviour with a module/fieldtype but my knowledge of pw module development and the related api work is not sufficient yet. Sure this kind of structure can now be created with subpages but this is not convenient for clients, since they don't have all the content on one page. One argument I've seen a lot is that there is too less of constraints for content creators/editors so they would mess up things or go nuts with laying out content. But the developer can exactly define which templates are assigned to that repeater. And those individual blocks/templates are very much under control of the dev so I strongly disagree with that argument.1 point
-
1 point
-
I just made another update to replace the fields settings with a AsmMultipleSelect for convenience. If you update, you want to select the textarea fields you want to use IM on. You also have to save the module setting at least once to make it work. And maybe reinstall the module to get rid of unnused settings, but not necessary.1 point
-
Starting in on a new site tonight and realized I never posted the last site we finished in March. www.la2050.org This was a information frontend site for a campaign to get people submitting proposals for a community funding project. Client was able to edit a ton of the site and never had any issues dealing with the backend. I learned a ton about markup/template organization from the threads here which were unbelievably helpful. Thanks everyone! Thanks Ryan!!!1 point
-
Ryan I was just thinking that it would be great if this was carried on in some way. I think the main advantage of having a whole site tutorial is that so many different methods come up that we all face in our projects: How you organise your templates How you go about changing permissions so that the end-user only edits what is needed Field types Navigation I think when it's all part of a project then it's easier to grasp and people will come out the other end of it with a much better idea on how to do their own projects. I know time must be very short and if there's any way I can help out, I'd be delighted. I also must stress that on a general level, the documentation here is outstanding, I just think an all-inclusive project walkthrough would be the icing1 point
-
Just a suggestion -- it would be good to add this to your tutorials list. It's an important part of what a lot of people are going to want to build. Took me a long time to find the relevant posts in the forums. Your reasoning and solutions are great, just difficult to find and time consuming to sift through the threads.1 point
-
Thanks Ryan, you are right. It was not TinyMCE interfering but the Markdown text formatter. Removing the Markdown text formatter so it's just a plain textarea field, and the standard check : if($page->summary_de) { ... } works as normal. If using the Markdown text formatter then the php trim function clears up any extra whitespace added, and the following test works : if(trim($page->summary_de)) { ... }1 point
-
Your first test (Test A) is what I would personally use, i.e. if($page->summary_de) { ... } Are these TinyMCE fields? I think you need to look at what's actually in the field. I have a feeling you've got some whitespace in there or something like one of these annoying TinyMCE droppings: "<p> </p>" or maybe just a carriage return or couple of spaces. Get the value out of an HTML context to see what's really in the field: echo htmlentities(var_dump($page->summary_de)); If you are dealing with possible whitespace in the field (as opposed to HTML tags or entities) then your if statement could account for that by doing this: if(trim($page->summary_de)) { ... } Don't bother with using isset() or is_null() -- those are really more useful in determining of the page's template carries those fields at all. But I don't think they are particularly useful for what you are trying to do.1 point