Leaderboard
Popular Content
Showing content with the highest reputation on 02/14/2016 in all areas
-
Thanks, glad you guys like it. I've lately worked on some projects here with a lot of pages deep in the site (and paginated no less), and the PageList bookmarks weren't cutting it. I found myself keeping two browser tabs open all the time so that I could keep my spot in the PageList. So I've been motivated to make this work better, but always got held up trying to figure out exactly how. Basically the goal has been to make the PageList behave as if it was an offcanvas panel that was always ready for you where you last left it. Back in PW 2.5 dev I was experimenting caches of the PageList, but the problem was that any changes in PageEdit could then make that cache stale, really limiting the utility of it. Last week I started messing with <link rel='prerender' href='...'> tags to the opened page list in order to keep a ready-to-use pre-rendered PageList that I could get to whenever clicking the "Pages" tab... it was quite cool, and instant, but also a real waste of background resources to be pre-rendering a PageList (and all the ajax requests) in the background while in the page editor. But just going through that process led to the current result, which uses JS cookies to remember the spot, and lets PageList perform a pre-render of what was previously split into multiple ajax requests. It's not as fast as using the link prerender tags but a lot more reliable and less wasteful of resources, so seemed like a good compromise. I had not seen that, wish I could say I had. But sounds like we're all on the same wavelength here! Great! Yeah it should run at the same speed regardless of quantity of children. I think one of the next improvements we'll want to look at is the ability to filter by text in the PageList. For instance, if you typed "something" in a text input, it would open all the branches directly to pages having the word "something" in their label. I think this has been brought up by others in the past too. The current search box in the masthead kind of does this already, but without any context of where those matches are, which is something the PageList could do. This could be handy in so many instances.6 points
-
A small contribution: Add an option to have ability to use Self-Signed Certificate on a given SMTP server with WireMailSmtp and PHP >= 5.6 What PHP say - source : https://secure.php.net/manual/en/migration56.openssl.php HOWTO: ----------- 1) In file smtp.php, class smtp_class, we add a member variable and a small function : /* Allow self signed certificate */ var $smtp_certificate = false; Function AllowSelfSignedCertificate($allow = false) { $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7"); $php_version=intval($version[0])*1000000+intval($version[1])*1000+intval($version[2]); if($php_version<5006000) return; if($allow) { stream_context_set_option($this->connection, 'ssl', 'verify_peer', false); stream_context_set_option($this->connection, 'ssl', 'allow_self_signed', true); } else { stream_context_set_option($this->connection, 'ssl', 'verify_peer', true); stream_context_set_option($this->connection, 'ssl', 'allow_self_signed', false); } } and, in the Connect() method, call the function just in before we check for the result of stream_socket_enable_crypto : Find : $this->OutputDebug('Starting TLS cryptograpic protocol'); if(!($success = stream_socket_enable_crypto($this->connection, 1, STREAM_CRYPTO_METHOD_TLS_CLIENT))) Replace to $this->OutputDebug('Starting TLS cryptograpic protocol'); $this->AllowSelfSignedCertificate($this->smtp_certificate); if(!($success = stream_socket_enable_crypto($this->connection, 1, STREAM_CRYPTO_METHOD_TLS_CLIENT)) 2) In the file smtp_message.php, class smtp_message_class, add a member variable : /* Allow Self Signed Certificate */ var $smtp_certificate = 0; In the method StartSendingMessage() , assign the new member variable: $this->smtp->smtp_certificate = $this->smtp_certificate; 3) In the file WireMailSmtpAdaptator, class hnsmtp, add a member variable : private $smtp_certificate = false; and in the method set_var_val(), add a case smtp_certificate for our checkbox : Find : case 'smtp_ssl': case 'smtp_start_tls': case 'smtp_debug': case 'smtp_html_debug': Replace : case 'smtp_certificate': case 'smtp_ssl': case 'smtp_start_tls': case 'smtp_debug': case 'smtp_html_debug': In the class constructor, add : $this->emailMessage->smtp_certificate = $this->smtp_certificate; 4) In the WireMailSmtpConfig.php file, add a field : add : $field = $modules->get('InputfieldCheckbox'); $field->attr('name', 'smtp_certificate'); $field->label = __('PHP >= 5.6 - Allow self signed certificate'); $field->attr('value', $data['smtp_certificate']); $field->attr('checked', $data['smtp_certificate'] ? 'checked' : ''); $fieldset->add($field); 5) In the WireMailSmtp.module file, add a settings to the getDefaultdata() : Find : 'valid_recipients' => '' // email addresses of valid recipients. String that we convert to array at runtime. Add after (take care of comma ','): 'smtp_certificate' => 0 // allow or not self signed certificate (PHP >= 5.6) Result : Hope it help. Sorry for my english3 points
-
Tracy Debugger for ProcessWire The ultimate “swiss army knife” debugging and development tool for the ProcessWire CMF/CMS Integrates and extends Nette's Tracy debugging tool and adds 35+ custom tools designed for effective ProcessWire debugging and lightning fast development The most comprehensive set of instructions and examples is available at: https://adrianbj.github.io/TracyDebugger Modules Directory: http://modules.processwire.com/modules/tracy-debugger/ Github: https://github.com/adrianbj/TracyDebugger A big thanks to @tpr for introducing me to Tracy and for the idea for this module and for significant feedback, testing, and feature suggestions.2 points
-
Current status: I can reproduce this issue on two fresh installations (latest 2.7.3 and latest 3.0.8). But I made one more discovery that was missing to reproduce the issue: the page field inside of the repeater field must be declared as required, than you can reproduce the issue (this is also the case in the original problematic page described in my first post). So, again, to reproduce this issue: Create a repeater field, which has a page field inside (page field must be marked as required). Create a pagetable field, allowing any template to be generated within it (like basic-page). Add the two fields to a template (like basic-page). Edit a page with the template basic-page. Add two entries to the pagetable field and save the page. Add a repeater item and select the current page in the page field. Add another repeater item and select not the current page in the page field. Save the page. Try to change the order of the pagetable entries and hit save. The re-ordering should not work. To get the ordering working: Change the selected page of the first repeater item from the current page to another page. Save the page. Re-order the pagetable items and hit save. Now the re-ordering should work. I think I found a bug.2 points
-
If you've added "namespace ProcessWire" to the top of your template files, then you template files are now running in the ProcessWire namespace rather than the global one. AIOM runs in the global namespace, since it's not specifically made for PW3. Since AIOM uses static method calls to add files (if I recall correctly), you would just need to change those calls from "AIOM::something" to "\AIOM::something", with the leading backslash. That tells PHP to access something from the global namespace. By the way, you don't have to disable compilation for templates individually if you don't want to. If you don't want the template compiler at all, just set $config->templateCompile = false; in your /site/config.php and the template compiler will be completely turned off.2 points
-
That's exactly right, filtering the entire page tree at once, not just 1 level of children in a branch.2 points
-
Greetings tooth-paste, I also love SVGs and look for ways to use them anywhere I can. For years, I have been wondering why they are not more widespread, but I think there is a resurgence in their popularity now! The level of control with SVGs is amazing, and when you couple them with the flexibility of ProcessWire to manipulate the SVG elements, the possibilities are tremendous. In theory, you could have an entire site built from an SVG DOM. You probably already know about these, but I wanted to include them here: http://raphaeljs.com https://d3js.org http://snapsvg.io Each one of the above resources has its advantages. Personally, I really like Raphael. Thanks, Matthew2 points
-
Actually I am, and have been for 18 years now, but that is a very different kind of love2 points
-
I love SVG Take a look at caniuse.com for the list of browser support: http://caniuse.com/#search=svg - I agree with @Mike Rockett - if a browser doesn't support SVG, then I don't support it. If you are going to allow your editors to upload SVG files, be sure to install the SVG validator: http://modules.processwire.com/modules/file-validator-svg-sanitizer/ because they can be a security risk.2 points
-
I have had a read about the way(s) one can embed it into CSS, where base64-encoded was title as sub-optimal as SVG is textbased (XML) and not binary data. They suggested this way: background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' width='120px' height='120px' viewBox='0 0 379 379'%3E %3Cg transform='matrix(1.25,0,0,-1.25,40,345)' id='g10'%3E %3Cg transform='scale(0.08,0.08)' id='g12'%3E %3Cpath id='path14' style='fill%3Argb(0,0,0)' d='m 1517.6,1767.02 c 138.62,0 251.01,-112.38 251.01,-251.02 0,-138.62 -112.39,-251.01 -251.01,-251.01 -138.64,0 -251.02,112.39 -251.02,251.01 0,138.64 112.38,251.02 251.02,251.02 z m -1.59,1264.99 C 679.137,3032.01 0.644531,2353.89 0.015625,1517.16 L 0,1517.16 0,749.051 388.961,403.559 l 0,1127.031 c 0,622.48 504.602,1127.06 1127.049,1127.06 622.45,0 1127.03,-504.58 1127.03,-1127.06 0,-622.41 -504.58,-1127.031 -1127.03,-1127.031 l -206.22,0 0,552.769 206.22,0 c 317.15,0 574.32,257.102 574.32,574.262 0,317.2 -257.17,574.32 -574.32,574.32 -317.16,0 -574.291,-257.12 -574.291,-574.32 L 941.719,0 1516.01,0 c 837.26,0 1516.01,678.73 1516.01,1515.99 0,837.28 -678.75,1516.02 -1516.01,1516.02' /%3E %3C/g%3E %3C/g%3E %3C/svg%3E") --- If you like and are brave, just drop the data uri into your browsers URL bar and press enter: data:image/svg+xml;utf8,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' width='120px' height='120px' viewBox='0 0 379 379'%3E %3Cg transform='matrix(1.25,0,0,-1.25,40,345)' id='g10'%3E %3Cg transform='scale(0.08,0.08)' id='g12'%3E %3Cpath id='path14' style='fill%3Argb(0,0,0)' d='m 1517.6,1767.02 c 138.62,0 251.01,-112.38 251.01,-251.02 0,-138.62 -112.39,-251.01 -251.01,-251.01 -138.64,0 -251.02,112.39 -251.02,251.01 0,138.64 112.38,251.02 251.02,251.02 z m -1.59,1264.99 C 679.137,3032.01 0.644531,2353.89 0.015625,1517.16 L 0,1517.16 0,749.051 388.961,403.559 l 0,1127.031 c 0,622.48 504.602,1127.06 1127.049,1127.06 622.45,0 1127.03,-504.58 1127.03,-1127.06 0,-622.41 -504.58,-1127.031 -1127.03,-1127.031 l -206.22,0 0,552.769 206.22,0 c 317.15,0 574.32,257.102 574.32,574.262 0,317.2 -257.17,574.32 -574.32,574.32 -317.16,0 -574.291,-257.12 -574.291,-574.32 L 941.719,0 1516.01,0 c 837.26,0 1516.01,678.73 1516.01,1515.99 0,837.28 -678.75,1516.02 -1516.01,1516.02' /%3E %3C/g%3E %3C/g%3E %3C/svg%3E2 points
-
Needed to show someone how to quickly setup some settings for various things in a simple text area: could be used for slider settings, site settings, etc; What it does: gives you a matching variable for each key of each line... 1.) setup a textarea field for the settings ; i'm calling it settings_ta 2.) add delimited settings, 1 per line; i use a pipe (|) delimiter; example: address|some info here facebook|https://www.facebook.com twitter|https://twitter.com phone|(999) 999-9999 3.) in your _init.php, get the settings - replace the page number and the name of your settings field: $settings_ta = $pages->get(1644)->settings_ta; $settings_lines = explode(PHP_EOL, $settings_ta); foreach($settings_lines as $settings_row) { $settings_pair = explode('|', $settings_row); ${trim($settings_pair[0])} = trim($settings_pair[1]); } more condensed version, for those of you who like brevity... foreach(explode(PHP_EOL, $pages->get(1644)->settings_ta) as $settings_row) { $settings_pair = explode('|', $settings_row); ${trim($settings_pair[0])} = trim($settings_pair[1]); } now you can do this in your templates: echo $address; echo $facebook; echo $twitter; echo $phone; Edit: made the code simpler....; 2nd edit - added trim to support using ace editor with tabs Addendum: as an added convenience, you could use the Ace text editor module which would give you a monospaced text field and the ability to use tabs for your settings, which could be more readable and easier to edit. The code has been updated to support this by trimming the exploded strings prior to generating the variable/value. address | some info here facebook | http://www.facebook.com twitter | http://twitter.com phone | (999) 999-99991 point
-
This week we've got a really nice improvement to ProcessWire's page tree, something that I believe everyone that uses the ProcessWire admin will appreciate. Also a big focus this week was on ProDrafts and wrapping that up so that we can release it and make it available to you. More on both here: https://processwire.com/blog/posts/processwire-3.0.8-brings-smarter-faster-page-tree/1 point
-
No, everything is checked there. No error was shown because of "!function_exists('t')" in the module.1 point
-
It's 4 decimals here: timer('timer A'); $view->package = getPackages(1, 'random')->first(); bd(timer('timer A')); Result: "timer A : 0.0047" (16) I can't use "t" because it's my translate function's name - maybe also a similar name collision is present there? Btw, in the post above where "timer" was introduced, the bd('first') should be bd(t('first')) if I see it right.1 point
-
That's weird - it was actually a git issue - I had already changed the filename locally to match the require statement, but git didn't update it when syncing. Looks to be fixed now.1 point
-
I think that sounds like a decent approach, so I just implemented it. Now there is no need to worry if for some reason you want to make direct calls via (Tracy\Debugger::method()) on a live site as non-superusers will just get the dummy methods which return nothing. I also just implemented the TD::timer() method, along with timer() and t() shortcut aliases. With timer() you can do: t(); // insert resource intensive code here bd(t()); to dump the results of the time to the debug bar.1 point
-
You want to sort by '-parent.sort, -created', but I'm not sure if this is even supported currently.1 point
-
How about making a dummy Tracy class with barDump/dump/log methods to load for non-superusers? (as a workaround) This way less resources would be needed.1 point
-
It's usable (e.g. processwire.com is using it already) but it's still in heavy development, so there aren't any guarantees. You'd make up you own mind if you want to use it. You could always give it a try locally.1 point
-
Aaaah, I didn't know that wire('templates') or $this->templates can be shown as an empty array in the $this->message output BUT still return something when doing foreach(wire('templates') as $t) { echo $t->name . '<br />'; } or $this->templates->get("name_of_other_template") Thanks a lot for your help, after realizing that, the rest was easy! <?php /** * ProcessWire module to create ServiceTypes by Pages * by Didhavn * 12.02.2016 */ class DidhavnAddServiceTypesByPage extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Add ServiceTypes By Page (Didhavn)', 'version' => 1.0, 'summary' => 'Add the ServiceTypes by getting Pages with Template "service-type"', 'singular' => true, 'autoload' => true ); } public function init() { $this->pages->addHookAfter('added', $this, "hookAdded"); } public function ready() { // PW API is ready, Controllers go here } public function hookAdded(HookEvent $event) { $page = $event->object; if (!$page->template) { $page = $event->arguments[0]; } if($page->template == 'service-type') { $newfieldname = 'servicetype_' . $page->name; $newfieldlabel = 'Service-Type ' . $page->get('title')->getDefaultValue(); $casetmpl = $this->templates->get("case"); $newfield = $this->fields->get($newfieldname); if (!$newfield && $casetmpl) { // field for this service-type doesn't exist -> create $f = new Field(); $f->type = $this->modules->get("FieldtypeRangeSlider"); $f->name = $newfieldname; $f->label = $newfieldlabel; $f->set('suffix','%'); $f->set('tags','servicetype'); $f->set('icon','fa-sliders'); $f->save(); // add field to template case $stsumfield = $casetmpl->fieldgroup->fields->get("servicetype_sum"); $casetmpl->fieldgroup->insertBefore($f, $stsumfield); $casetmpl->fieldgroup->save(); } } } }1 point
-
Oh my goodness, now it’s getting really weird. I narrowed the problem down. I have a repeater field on said problematic page. I use the repeater to generate a subnavigation for the page in the front-end. The repeater field has a page field in it (called subnav_page). I have 4 or 5 repeater list items in total. When the page field in at least one repeater item points to the problematic page (in the case of the problematic page the page field of every repeater item must point to the problematic page [which is the one I am editing right now], because the subnavigation should only consist of anchors pointing to specific sections on the page in the front-end) than the ordering does not work, like described. If the page field of every repeater item points to any page except the problematic page, than the ordering works. I double and triple checked this. Also I checked, that the subnav_page page field is only used in the context of the repeater field, nowhere else. There is really no evident connection between the repeater field and the fields inside of the repeater field, and the PageTable field. But apparently, there is. I have to take a break, this is just too weird …1 point
-
1 point
-
New tab/panel isn't hard to do at all, but I wonder whether just having that section always expanded would be ok/better? There are so many options and ways to present info that I am not totally sure the best option yet. I'd really love some thoughts from others about what they think they would use/access most often. Perhaps I could add several PW tabs/panels with different elements on each. Anyone have any ideas on what else they would like to have accessible and what should be grouped with what? EDIT: I have just made the Page Info section open by default so a hover over the PW tab is enough to see that info. Still amenable to making separate tabs/panels if that is the consensus though.1 point
-
Yes, by adding $config->templateCompile = false; to config.php. https://processwire.com/blog/posts/processwire-3.0-alpha-2-and-2.6.22-rc1/1 point
-
1 point
-
Has anyone used this module on 3.X branch? Using 3.0.8 i'm getting stuck on the 'Step 2' screen. It does not seem to grab the fields from the template i want to use for the pages to import. In the screenshot 'menu-item', but i've tried in a number of ways and different parents but no luck. I'm not getting any errors or anything but i get empty field dropdowns. I'm aware that the module does not yet indicate compatibility with 3.X but most 2.X modules i tried worked fine with 3.X. Edit: for (cross)reference, a Github issue has also been made about this by another user. https://github.com/ryancramerdesign/ImportPagesCSV/issues/121 point
-
There are handy Grunt and Gulp tools, e.g. http://mattsoria.com/killersvgworkflow/ For a site that used tons of icons (including :hover versions), we used Grunt tasks that: - scanned a folder full of SVGs - created an SVG sprite - wrote a .scss file with classes for each icon (based on some simple naming conventions) - plus: did the same thing, but as PNGs (IE9 / old browser fallback) I wouldn't use SVGs in HTML emails though. There are still various email clients (web-based, standalone desktop or mobile apps) that don't support it. https://css-tricks.com/a-guide-on-svg-support-in-email/1 point
-
ok is the installation in a subfolder ? e.g. www.yourdomain.com/ <- index.php // index of pw or www.yourdoimain.com/subfolder/index.php //subfolder is the name of your folder Than you have to change to # RewriteBase / RewriteBase /subolder/ # RewriteBase /~user/1 point
-
Was going to write a longer reply, but BitPoet already summed up most of my thoughts One thing I'd like to add to the "benefits" section is that with ProcessWire you can be certain that you won't run into issues if that "simple site" needs to grow. Sure, you could always ditch all you've got and start from the scratch, and sometimes that's a good idea anyway, but ProcessWire is more than capable of handling both small and large needs. That being said I don't really know CloudCannon that well, so it might also be capable of handling larger needs, but based on what I've seen so far that doesn't seem very likely. At the very least their pricing model ($$ per month per user, if I understand it correctly) would make CloudCannon really expensive for most of the clients we work with1 point
-
I just gave the documentation for CloudCannon a read, and I can't agree with you. You still have to think about how you structure it, decide what information to turn into individual fields (editable regions) and how you name them for translation (manually give every editable region a unique data-i18n key) and styling. The example for the navigation with an endless list of if-statements just to decide which link should have the "active" css class set is enough in itself to make me never ever want to use it as a CMS. The "problems with PW" you mentioned are things every developer should always (at least try to) work out in advance before he/she starts working on a site, no matter what platform. Even a static site needs fixed places for pieces of identical semantic value and proper naming of HTML elements for the CSS and JS that is referencing it to work and still make sense after a year. If you encounter things that you always need to do the same way to get started with a website in PW, you can create a site profile, use one of the Exporter modules or write a short script. This is one of the big strengths of PW: to make complex recurring tasks easy.1 point
-
The forum is your friend https://processwire.com/api/coding-style-guide/ https://processwire.com/talk/topic/3961-new-to-cms/ https://processwire.com/talk/topic/2994-learning-php/ https://processwire.com/docs/tutorials/but-what-if-i-dont-know-how-to-code/ https://processwire.com/talk/topic/6030-learning-php-where-to-learn-just-enough-to-make-living-w-pw-easier/1 point
-
Yes. it will count each page only once per session. So, if the user refreshes the page or use the back button, it will count only once.1 point
-
To extend upon what LostKobrakai said, by basic understanding of PHP, I would say: how to set variables how to use the if control structure how to loop through an array (foreach) how to output something (echo) Those basic concepts apply for any programming language and will be heavily used in your templates. Master those with PW's easy API and you'll be like 80% of the way there.1 point
-
Aha. So your saying that if the Session var is set then there is no counting ? And if there is no such Session var it is set and the count goes up one ? Just so i understand.1 point
-
1 point
-
A settings field based on a hooked Profields Table. When running the code (in the spoiler), superusers are able to edit, drag & delete all, while other users are limited to edit the setting only. (Thanks MacRura for the idea) Superuser sees: Everybody else sees: Code lives in the spoiler. Maybe some time I build a Module for this one.1 point
-
If you prefer some type of delayed output, you also can use both (regular and ajax) very close together: $out = ''; $out .= {html head part}; $out .= {my menu content}; $out .= {some other content}; // her we come to the individual content if ($config->ajax) $out = ''; // delete all collected output til here and start new $out .= {my individual content}; //... collect until individual content is complete, then if ($config->ajax) { echo $out; // send it out as html exit(); // stop any further processing } // if it isn't a ajax call you collect also footer etc. $out .= {my footer content}; // send out the complete html page echo $out;1 point
-
A very simplified example. Reloading only the page content via ajax: if( !$config->ajax ) include("head.inc"); echo $page->body; if( !$config->ajax ) include("foot.inc");1 point
-
That's my article, using Ajax is quite easy in PW, just make an Ajax call to your page, now the HTTP Header contains Ajax header in it, so $config->ajax will flag as true when it is an Ajax call and false if not, Do this 1. Make an Ajax Call to the Page 2. var_dump something if Ajax and exit and you will see your result 100% cleaner than WordPress and i stick to that statement, also thanks for reading my blog. If you have something you want me to write on please let me know, quite bored at home.1 point
-
you can use it in several scenarios: Progressive Enhancement of forms: Return json for inline form validation (using the same url for the "good old form roundtrip action" and json_encoded responses: $response = array( error => true, status => 'unsubmitted', msg => 'no valid form data given' ); do { if ($_SERVER['REQUEST_METHOD'] != 'POST') break; $response['status'] = 'submitted'; if(!$someValidator->validate($_POST)) break; // more validation logic here... $response['error'] = false; } while (false); if( $config->ajax ) { if (!headers_sent()) { header('Content-type: text/json'); header('Content-type: application/json'); } echo json_encode($response); return; } Rendering different templates when urls are accessed via ajax: $template = $config->ajax ? "ui/projects_ajax.php" : "ui/projects.php"; $content = wireRenderFile( $template, array( "title"=>$title, "CategoryData"=>$pages->find("/categories/,include=hidden"), "PageData"=>$page )); ... we use this technique here (in combination with pushstate/history.js): http://www.accom.kg/ - If templates are accessed via ajax they are rendered without footer and header. This way we only load the necessary parts to be displayed. If the user (or google) visits the "real" page, navigation and footer are rendered. Redirecting users that accidentally visit some api endpoint that should only be used via ajax: if( !$config->ajax ) { $session->redirect('/'); } // API-LOGIC HERE. .... plus a billion other examples1 point
-
This module does two things: 1. Gives you the ability to perform text matching on page paths/urls with selectors, i.e. $pages->find("path%=blahblahblah"); 2. Adds an index of page paths in a separate table, potentially making retrieval of a page by path faster. Meaning, it can increase the performance of $pages->get("/path/to/page/"); and similar types of retrievals. I honestly haven't used this module all that much. Its performance benefit is theoretical and I'm not sure it's actually measurable. As a result, I'm not sure I'd necessarily install it unless you want to perform text matching on page paths. This one will probably be removed from the core in PW 3.0 and kept as a 3rd party module.1 point