Leaderboard
Popular Content
Showing content with the highest reputation on 04/28/2013 in all areas
-
So, I've been seeing some email-related topics around here and actually had quite a few struggles of my own with this very subject myself lately. Thing is that sending email should be easy, but it's not always that; especially for those who have to work on multiple, low-price (and regrettably often low-quality) platforms that may or may not provide proper mail servers.. or prefer to host their services themselves and still want to avoid setting up and maintaining a mail server. Hosting a mail server can be real pain in the ass when things don't work like they should, not to mention that most people have very little knowledge about DNS entries etc. this requires. Anyway, long story short: yesterday I started thinking that wouldn't it be sweet to have a layer of abstraction within ProcessWire for sending email? Of course one could still use PHP mail() -- there's no way and no sense in even trying to stop that -- but using a common gateway would definitely bring in some extra value. This layer I'm talking about could by default use built-in PHP mail() but also make it possible to override it, thus allowing multitude of options that PHP mail(), being bound to Sendmail / it's alternatives, can't offer without additional server-side software (such as Nullmailer.) By making sending emails hookable it could also enable all kinds of interesting tricks to be done when mail is sent -- such as writing a custom log file, sending another email to someone else, updating local content (I'd imagine that this could be useful for building newsletter platform, for an example) and so on. Since words tend to fail me at times like these, I put together a quick proof of concept of what I'm talking about here, accompanied by one example of what could be achieved by doing this: A very simple yet functional Mailer class Two commits on top here list all the changes I've made in my PW fork to make this work -- including the fact that I've altered some default modules to use $mailer->send() instead of mail() SwiftMailer module, again very simple but fully functional (though only tested with Gmail SMTP) drop-in replacement for PHP mail() So, what do you folks think of this? Please keep in mind that this is just a suggestion and I'm not saying that this is the right path to take especially considering that it would add another API variable -- it just felt like best option here and I couldn't think of cleaner way to achieve it.8 points
-
I like it! There is no better way to propose ideas than this Teppo. First: Yes, simple wrapper is definitely needed. I think it should take same params than mail() does - and just like your proposal works. What I am not sure is that if replace hook is way to go here though? Maybe having general config module (or just config.php) where one could select which mailer is used? Also - not sure about this one - but sometimes one might want to set mailer on code level, something like this: $postmark = $modules->get("MailerPostmark"); $mailer->provider = $postmark; $mailer->send(...); That would allow to having multiple provider modules installed and still having control which one get's used (and possibility to use them in different parts of the application). Having this supported in core there wouldn't be any reason not to build newsletter system in PW...3 points
-
I've been using this module to fill in a database of movies lately. Lets just say that there are "quite a few" of them and it's a lot of work. My point here is that since I happened to need a few custom fields that were always there, I modified module source just enough to include those -- no need for a generic option, just couple of lines of PHP and voilà: inserting movies just got a lot easier! I'm sure this is not what you were looking for there, just wanted to point out that modifying code of this module like that is quite easy to do and can save a lot of time if you're facing importing a lot of data by hand. That's one benefit of free software / open source, you know..2 points
-
If you have few variations of sort you could do it with a switch statement: switch ($get) { case "name DESC": $sort = -name; break; case "name ASC": $sort = -name; break; // and so on... } If there are more variations you can automate it like this: $sort = explode(" ", $get); $order = $sort[1] == "DESC" ? "-" : "" ; $value = $sort[0]; $pages->find("template=basic-page, limit=10, sort=$order$value");2 points
-
Yes helper functions like this can be included using a separate php like in the head.inc and used throughout your templates. I extracted this function from a module I have for a project. This module has various helper function and then I load it in the templates. It's much the same as if I would include a php with functions and just personal preference. For example: $helpers = $modules->get("TemplateHelpers"); then use it like this where I need it. echo $helpers->wordLimiter($page->body); I'm not sure what you mean by applying the function to the body. I use this function to create teaser texts that are limited, and show the complete body only on the detail page. Of course you could modify the body output, that every time you do an echo $page->body, it will run it through a function, but I'm not sure this is a good practice. This using a hook on the formatValue of textfields would do it: (directly in template like a include, or by making it a module) function wordLimiter(HookEvent $event){ $field = $event->argumentsByName('field'); if($field->name != 'body') return; $str = $event->return; $limit = 150; $endstr = ' …'; $str = strip_tags($str); if(strlen($str) <= $limit) return; $out = substr($str, 0, $limit); $pos = strrpos($out, " "); if ($pos>0) { $out = substr($out, 0, $pos); } return $event->return = $out .= $endstr; } wire()->addHookAfter("FieldtypeTextarea::formatValue", null, "wordLimiter"); // now this will trigger the above hook echo $page->body; But it's a little cumbersome, as you can't set the limit. Also this strips tags and on HTML text you'll lose formatting. But just to show adn example what is possible. From your post I guess you like to do something like: echo $page->body->limit(150); // not possible It's not possible to do this, because the $page->body, body is just a string and not an object you could add methods to it. But something like the following would be possible using hooks. echo $page->wordLimiter("body", 120); You can use addHook to add a method wordLimiter to page: function wordLimiter(HookEvent $event){ $field = $event->arguments[0]; // first argument $limit = $event->arguments[1]; $endstr = isset($event->arguments[2]) ? $event->arguments[2] : ' …'; $page = $event->object; // the page $str = $page->get($field); $str = strip_tags($str); if(strlen($str) <= $limit) return; $out = substr($str, 0, $limit); $pos = strrpos($out, " "); if ($pos>0) { $out = substr($out, 0, $pos); } return $event->return = $out .= $endstr; } // this will add a custom method to Page object wire()->addHook("Page::wordLimiter", null, "wordLimiter"); // now you can do this echo $page->wordLimiter("body", 100); // or this echo $page->wordLimiter("summary", 100);2 points
-
Hey, is this new? Cool: mods.pw/3y EDIT: uhm, sorry for beeing OT! Just got excited.2 points
-
Markup Simple Navigation Module While there was a lot of people asking how to make navigation, and there were many examples around already (apeisa, ryan...) I took the chance to sit down 2-3 hours to make a simple navigation module. It has even some options you can control some aspects of the output. Installation: 1. Put this module's folder "MarkupSimpleNavigation" into your /site/modules folder. 2. Go to your module Install page and click "Check for new modules". It will appear under the section Markup. Click "install" button. Done. Technically you don't even need to install it, after the first load call ( $modules->get("MarkupSimpleNavigation") ) it will install automaticly on first request if it isn't already. But it feels better. However, it will not be "autoloaded" by Processwire unless you load it in one of your php templates. Documentation: https://github.com/somatonic/MarkupSimpleNavigation/blob/master/README.md Modules Repository processwire.com https://processwire.com/modules/markup-simple-navigation/ Download on github https://github.com/somatonic/MarkupSimpleNavigation Advanced example with hooks creating a Bootstrap 2.3.2 Multilevel Navbar https://gist.github.com/somatonic/6258081 I use hooks to manipulate certain attributes and classes to li's and anchors. If you understand the concept you can do a lot with this Module.1 point
-
1 point
-
Hello professional PW world! Not being a developer/designer myself (its rather my hobby), I've liked PW for its simplicity and flexibility and even developed simple site with it. However more complex sites require time to grow professionalism in PHP/JS/design/etc - something that I can't get quickly and without impact on my main work. As a result, I'd like to post job here. In brief - I'm looking for professional PW + PHP developer for full-cycle PW-powered site development. Site will be analogy of coachup.com. Differences come from content that will be provided during development (another business area, specifically, education + content language is Russian (but I'll need to leave possibility to easily switch to other languages)). All the rest (front-end design concept, site structure, frond-end and back-end functionality, etc) is the same. Please check this site to get full picture and understand scope of work. Take into account that functionality includes work with external APIs: authorization from social sites, Google maps, payment gateway, support chat. Hope this helps to estimate budget and time. Please contact me with questions and proposals at andrey.valiev@hotmail.com. Or leave comments here. Thank you! Best regards, Andrey P.S. As I plan to develop few other PW-powered sites, more job may come.1 point
-
In a rare display of personal work I’ve made a photographic site to show some of my pics. I hope you like it. http://stlmv.in/mw1 point
-
You'd have to get into tens of thousands of pages, if not more, before you would be able to detect a speed difference. That's been my experience at least. MySQL has apparently optimized their LIKE terms very well, or have figured out how to optimize to an index when it's there.1 point
-
All modules now have their own short URL off mods.pw. The letter combo used is the base 62 value of the module's ProcessWire page ID minus 1000. For example "3y" translates to 1246. Just a way to keep them as short as possible.1 point
-
The only reason the default profile uses a head (header) / foot (footer) naming convention is because this is what WordPress does, and it's not far off from what Drupal does. So the point is to provide some point of reference relative to other systems. It's not really the best approach to use once you know what you are doing… though it's also fine to use if it suits your needs.1 point
-
Regarding Approach #1, I think you'd want to use the LanguageSupportPageNames module included with PW 2.3.0 dev branch. I'm responding to your special cases with that context: You have checkboxes next to each language page name. This controls whether the page is published in each language. There is no need to keep track of this since the URL structure dictates the language. This also makes it very SEO friendly. ProcessWire takes care of setting the user's correct language for you, based on the URL. That's what code internationalization is for. For example, an editable footer: <p id='footer'><?php echo __('Thank you for visiting. Copyright 2013 by Somebody.'); ?></p> The following is replying to approach #2, separate trees: The structure is up to you. Whether or not you start your root with an "en/" for your default language is based entirely on how you structure your site. So if you don't want to have "en/" (for example) for your default language, then don't built off a page called "en". Also not necessary since structure would dictate language. You would examine the $page->rootParent to determine language and set it at the top of some common include file (like a head.inc or init.php): if($page->rootParent->template == 'language-home') { // or whatever your template is called $user->language = $languages->get($page->rootParent->name); } else { $user->language = $languages->get('default'); } The same about code internationalization above applies here. Anything static text you put in a __() function becomes translatable. If something is translatable then it is also editable, even for the default language if you want. If you still didn't want to have text originate from the template, then you could always create a settings page in each tree. I would probably just add my "footer_text" as a field in the language-home page.1 point
-
You will still see the page if you are logged in as super user. Logout or access that url in the browser's private mode to check if it's visible to general public. For maintenance, besides Pete's module check also these tips of mine http://processwire.com/talk/topic/3324-maintenance-mode-message/?p=32769 http://processwire.com/talk/topic/2475-quick-tip-for-testing-on-live-website/1 point
-
Perhaps http://modules.processwire.com/modules/maintenance-mode/ would help here? Not 100% sure if it'll still work with PW 2.3 though, but might be worth trying1 point
-
I think you've got it right. Because a removeAll(); is an action that is ultimately reflected in the database when the page is saved (rather than when you called removeAll), it's a good idea to do that save() after the removeAll() so that it's not getting mixed in and potentially voiding the other operations. Also wanted to recommend adding validation to this: $page->invoice_terms = (int) $input->post->edit_status; Something like this: // using find rather than get ensures the item is retrieved with access control $item = $pages->find((int) $input->post->edit_status)->first(); // double check the item you are trying to add is what you expect by checking // something like the template or the parent, etc. if($item && $item->template == 'your-expected-template') $page->invoice_terms = $item;1 point
-
No it's 2.3 compatible, but every new version has a new checkbox to check and I haven't done it yet. I think there's many modules that suffer from this.1 point
-
Hi isellsoap, Currently not possible, but maybe in future. Check this thread out: http://processwire.com/talk/topic/2269-repeater-fields-most-recent-to-top/ If you have 'lot' of repeater items, you may also consider to add the data as pages. This way you can define the sorting.1 point
-
This also from the API docs.... http://processwire.com/api/selectors/1 point
-
Hi kongondo, There's no reason to use a while loop in the situation where you are just iterating over the pages found. Generally: If you need to loop over a set of data, you're free to choose the type of loop (for, while, do-while). However, it depends on the situation which one you take As for your example, you could do it in a while loop like this: $i = 0; while (count($results)) { $p = $results->get($i); $rows[] = $p; $results->remove($i); $i++; }1 point
-
while(youcan < youshould) { // do what you want } Well use foreach... It's just a matter of preference and you could even use for() foreach() while() A while loop with a PageArray would look like this: $res = $pages->find("template=somexy, limit=10"); $i = 0; while($r = $res->eq($i)){ echo $r->title . "<br/>"; $i++; }1 point
-
How very annoying... it works without explanation. I uploaded my local files via FTP, and that worked. I then downloaded a zip from the repo and uploaded that via FTP, which also worked. I then created a new directory and cloned the repo to there, and it also worked. But still the broken site wouldn't respond, and Git seemed to think it was the same as the repo. So I deleted it, recreated the directory and cloned the repo again... and it worked! Yet that is exactly how it was created in the first place. Hate it when something gets fixed without any "real" explanation. Can only guess a file was corrupted as suggested by Soma. Thanks for your help. At least got my looking in the right places.1 point
-
1 point
-
Hi Rick, head.inc and foot.inc don't represent literally the html <head> or <footer>, they are just there to hold code that is common to most pages. That's why you find navigation and summaries there. They could be called top.inc and bottom.inc or start.inc and end.inc, but those names are generally recognized among developers, so it makes sense to use them on the default install. You are the one choosing the level of editability (my spellchecker doesn't like this word) of the sites you design. Some times it makes sense that everything is editable, and processwire for sure allows you to do this, other times you want a bigger control over some aspects of the website, and make it available for the editors to change only what's necessary. In the latter case it makes sense to have some content hard coded. You should do it, we all are. The default install serves only as an example. Ryan created the most simple site that still has some complex snippets of code, here and there, that you can take as example, with few templates and fields, but that represent a lot of you can do with pw. Do as you wish—use some code and some of the fields and templates, or just wipe it all and start from a blank state. But make sure you learn from it because it's full of nice details1 point
-
A huge thanks to Diogo who has been helping me debug this. He eventually found out the cause of the error was the $page->invoice_line->removeAll(); line. It seems to require a save() after this line and then a further save at the end. if ($error == 0) { $page->of(false); $page->invoice_line->removeAll(); $page->save(); $page->of(false); $page->title = $sanitizer->name($input->post->number); ... $page->save(); Could Ryan confirm this is the correct way? Diogo, mucho obrigado1 point
-
If you want to integrate Google+ Comments in your ProcessWire website, just follow the instructions from an article on Browsing the Net. In summary, insert the following HTML code into your template: <script src="https://apis.google.com/js/plusone.js"></script> <g:comments href="<?=$page->httpUrl?>" width="642" first_party_property="BLOGGER" view_type="FILTERED_POSTMOD"></g:comments> Change the width accordingly and in case you have a Google+ profile, link your page with Google+ profile to enable moderation features.1 point
-
$pages->get('name=$name'); $name won't get parsed. You need in this case have double quotes "name=$name" or PHP doesn't replace $name with its value.1 point
-
ok, sorry totally worked it out and was easier than expected (like most things in processwire). $widgets = $page->side_bar_widgets; foreach ($widgets as $widget) { $name = $widget->name; echo $widget->render(); }1 point
-
"Create Pages" defines if users with specified role can add pages with that particular template.1 point
-
Another update for czech localization pack is done. Current version: 0.9.3 (88 files) Changes: Added comments module localization Added some missing strings Updated several strings pw_czech_093.zip1 point
-
@jmartsch, I think you encounter the same as the previous poster? is openssl installed? I just pulled in an update from petsagouris with multitude of changes, one of which checks for the openssl module being installed. udpate 1.0.7 - multitude of fixed and code cleanup (@petsagouris) - added check for openssl module required for https download stream (@petsagouris) - added back to Modules Manager button on download/update screen1 point
-
A past client of mine which I did a wordpress site for a couple years back is now having issues with their site layout. It's been forever since I dived into wordpress and after playing with PW for a little over a couple months, I really don't even want to attempt trying to fix the wordpress issue. In fact, I thought I eliminated every possible way an issue could come up for them :/ Anyway, I think to myself, "I can convert this entire wordpress site over to PW in a day or two and actually save myself a headache from the wordpress template forest!! Food for thought, even though I tried to make it as user friendly as possible and wrote a user guide, it seems they have never uploaded any photos, videos, or anything of the sort. It's a shame really, and I think it had a lot to do with how Wordpress is still unfriendly to some really non-technical clients. So, I am looking forward to blowing their minds when I show them the beauty of Processwire My rant...1 point
-
Just wanted to add that parent=1006|1003 will only give direct children of those two pages and not recursively all children and grandchildren... So once you get on 3rd level it will stop. This may not an issue just a limit of this use. There's a select field has_parent=1006 which does include all that are in that parent with all subchilds, though it doesn't allow for multiple only one ID. So going templates or checkbox way is most flexible and solid solution. Edit: you could work around the limit also with something like this (being creative) <ul class="nav"> <?php echo $nav->render(array('selector' => 'id|has_parent=1006', 'outer_tpl' => '||' )); // outer ul empty ?> <?php echo $nav->render(array('selector' => 'id|has_parent=1003', 'outer_tpl' => '||' )); ?> </ul>1 point
-
Another would be to hand the items to the outer_tpl. $customPage = $pages->get('/.../'); $item = "<li><a href='{$customPage->url}'>{$customPage->title}</a></li>"; echo $modules->get('MarkupSimpleNavigation')->render(array('outer_tpl' => "<ul>$item||</ul>"));1 point
-
Wanze's example is just demonstrating a bit to get you started. You can hard code as little (or as much) as you want. When we present examples here, it's sometimes easier for people to follow if we hard code some things to make the context clear. But that doesn't mean you have to (or should) do that in your own implementation. Basically, we're trying to teach rather than do it for you, so that you can apply what you learn in a much broader context. In addition to the API page Wanze mentioned, you might also want to look at the /site/templates/sitemap.php file in the default profile. This demonstrates creating a navigation tree for an entire site, and may serve as a good starting point for what you are trying to do.1 point
-
One solution I used: Give your main menu items that should redirect to the firt sub menu a "redirect" template. Then in your template, simply add this code: $children = $page->children; if (count($children)) { $session->redirect($children->first()->url); } else { //This page has no children to redirect... throw a 404 or do other work throw new Wire404Exception(); }1 point
-
You can go to PW's unofficial complementary documents for this http://php.net/manual/en/function.date.php1 point
-
One problem I noticed while using (and really enjoying!) this module. If I have this kind of structure: /news/ (tpl: news) /pw3-released/ (tpl: news-item) /ryan-looking-for-drupal-work/ (tpl: news-item) /soma-takes-over-pw-project/ (tpl: news-item) And all those pages use Simple Navigation with these options: $options = array( 'collapsed' => true, 'selector' => 'template!=news-item' ); When looking one of the news-item pages it will render the navigation just fine (excluding the news-items, but showing the "/news/" page. But what is missing is the "parent" class from the news page in nav list. Not sure if that is intended or something that is difficult to fix, but it is frustrating to lose css class there. We are still under the news-page.1 point
-
Okay, so I'm different. Usually, people want to exclude stuff from an automagically generated navigation – I would like to add stuff. Let's see if I can explain this: I have a primary navigation which this module is just perfect for. But the site also has a secondary navigation in the footer, so there should be an item in the primary nav which skips to said secondary nav in the footer. So basically, I would have to append an item to the nav generated by the module, technically another list item containing a link to an anchor on the same page. Conveniently, this "skip to service nav" item would be the last item of the primary navigation, so I came up with this: 'outer_tpl' => '<ul class="clearfix">||<li><a id="skip-to-service" href="#service">Service</a></li></ul>' which works fine unless I'm on a page which has children (<li class="current has_children">). In that case, outer_tpl is "reset" to '<ul class="clearfix">||</ul>' or something, at least the "appended" list item is not rendered. Not being a PHP coder myself, I can't figure out if this is intended behaviour of the module or maybe a bug. (Although I'm aware I might be misusing 'outer_tpl' here.) I also thought about different approaches to realize that kind of nav item, maybe by using a "dummy page" or something, but I can't figure out how to do that. (Suggestions welcome, of course.)1 point
-
I like this module as it reminds me of WayFinder for MODx - definitely one of the most useful tools I used to use for getting a site up and running quickly.1 point
-
This goes little off topic: IMO good way to learn is to be brave and publish stuff that you have done for feedback. This forum is one fine place to do it (and I remember you have done also) - it's great to get feedback and is many times beneficial for others too! I don't know how to thank Ryan and others enough for all the learning I have got from here. I have also found that there are some concepts that are very common in web development (php & js for me) and understanding those will speed up your learning (not saying that I have grasped these all, still learning basic stuff also..): arrays, multidimensional looping those arrays functions (especially those that return something) classes and objects Web dev basics: server side vs. client side? sessions, cookies, databases. http-basics: post, get, headers... Also there are super simple things that we waste a lot of time. Things like string manipulation or simple maths. If you have problems like that and google doesn't help you right away, then just ask for help - it will help you learn faster. Also - learn to love php.net - ugly but working docs there! There will be boring and depressing phases when you learn slower and even feel going backwards (you realize how much you don't know and it feels bad ). And then there are those awesome moments when you feel like everything is possible and you just want to build and learn more. Most important thing is to keep building stuff. There are those wizard brain lies that keep telling people that they don't know and they will never know something - that they are just incompetent for doing stuff like coding/painting/music etc. "You are just a designer, don't bother trying to code something yourself, it will never work" or just the opposite: "You are just a developer, don't even try to build something beautiful or even usable"... how much better software we would have without lies like that?1 point