-
Posts
6,798 -
Joined
-
Last visited
-
Days Won
158
Everything posted by Soma
-
Modules with class names? Programming and naming schemes ...
Soma replied to thomas's topic in API & Templates
This is an simple example module one can create within minutes to add a custom template variable "$channel" you can use in templates if you load the module (note it's not autoload). The important part here is the $this->fuel->set("channel",$this); in the init() function, which creates the template variable (like $pages) and attaches the class to it with $this. Just a simple $modules->get("ModuleName"); will do it in the start of you main template or, you could also make it autoload if you really want to load in on every request (front and backend) Create a module MyChannels.module with something like this, install it and you're set. You could create also one module for tags. class MyChannels extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'My Channels', 'version' => 100, 'summary' => 'Useful functions for templates.', 'href' => '', 'singular' => true ); } public function init() { $this->fuel->set("channel", $this); } public function countMedia() { $count = $this->pages->count("template=media-channel"); return $count; } } To load the module in a template $modules->get("MyChannels"); // load the module // now you can use echo $channel->countMedia(); Another method would be to have a helper module, that also isn't autoload, but you instance it on a variable and use it to call different module public methods. Same code but slightly different in that you only have one module with lots of functions and use it slightly different. class MyHelpers 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' => 'My Helpers', 'version' => 100, 'summary' => 'Useful functions for templates.', 'href' => '', 'singular' => true ); } public function init() { // maybe good to add hooks here if needed in the project } public function countMediaChannel($options = null) { $count = $this->pages->count("template=media-channel $options"); return $count; } public function countMediaTag() { $count = wire("pages")->count("template=media-tag"); return $count; } } To load this module in a template $mediahelper = $modules->get("MyChannels"); // load the module // now you can use it echo $mediahelper->countMediaChannel(",include=all"); I do this a lot, and sometimes only because it's fun and feels good, but also helps. Everybody can do it, even I. This is only some pseudo code, but there's nothing else involved. If you familar with PW API in templates you can code modules. Also take a look at the HelloWorld.module that comes with the basic-profile install. There's also more examples like properties -
Some PW template syntax to the table? <? if(count($page->gallery)): ?> <h6>Images</h6> <? foreach($page->gallery as $slide): ?> <a rel='prettyPhoto[pp_gal]' title='<?= $slide->gallery_caption ?>' href='<?= $slide->gallery_image->url ?>'> <img class='peKbGallery' data-delay='<?= $slide->gallery_delay ?>' src='<?= $slide->gallery_image->url ?>' alt='<?= $slide->gallery_caption ?> (Click to enlarge)' /> </a>"; <? endforeach; ?> <? endif; ?>
-
:'(You made me curious, but my ajax search module still works with dev branch.
-
Just experimented also a little and made a little example based on Martjin's code. With some improvements and simpler add image routine. No need to create a new PageImage as the page already has PageImages field. Just add the path to the file and save page. This can also be a remote web url. Also this example shows how error handling can be done. I also used a "/.tmp_upload" folder to upload images first and only add to the page if everything is valid. Since $u->execute() uploads the file to the destination specified, it could be a security issue, if not dealed correctly with it. As far as security goes this folder should be made publicly not accessible via htaccess (in comment). In 2.3 you could maybe use built in restriction to files on pages, but not sure it would be appropriate here. Further, I delete the images uploaded in tmp folder in either case. This is all example code and may even need additional security for real public uploads. (mime types check of files by the WireUpload is sufficient? Ryan?) I've put the code on gist.github: https://gist.github.com/4150974
-
Hey marcin, there's some threads already about it.
-
Guys, he's bootstraping. CLI command line interface... index can also be used in command line. Ok. Your code looks right. It's correct, you have to use $wire or wire("pages") in bootstrap. I just tested ur code 1:1 and it works well. Name, Title and Body are all filled in on all pages. Huh? Actually the cleanest and simplest way to use is if($p->id) ...
-
CSS: Getting images overlay to play nicely with TinyMCE output
Soma replied to onjegolders's topic in Dev Talk
Works fine if I leave out the extra div wrapper and add one line to the css to make the link tag display:block; http://jsfiddle.net/pJA9M/4/ Maybe also consider using such a tool like jsfiddle to post problems like this, as it's easier for one to have a look. Avoid posting code that much Another try: http://jsfiddle.net/pJA9M/10/- 6 replies
-
- image overlay
- tinymce
-
(and 1 more)
Tagged with:
-
The only way to prevent this issue is to install "PageLinkAbstractor" module and it will give you additional options on textfields. This will parse urls and add subfolder on runtime. http://modules.processwire.com/modules/page-link-abstractor/
-
With a little trick you can get this to work. Install this module http://modules.processwire.com/modules/page-list-image-label/ and you'll see an image preview. If you then set the page field to select the input "PageListSelect" you'll be able to see the image label of the page. The PageListSelectMultiple select you'll only see the image when choosing from the tree.
-
Have each "banner" a page with a template "banner" which contains an image field and possibly more fields for additional meta data. Create a template "banners" (only field title) and only allow children to have "banner" template. Create a page "Banners" using that template. Now create banners as subchilds of the Banners page. THen create a page field "select_banner" and allow it to select pages with template "banner", and have the inputfield a simple select. Attach "select_banner" to the template you would like to select a banner. Use that to render the image or whatever from the selected banner. This is one way of doing it which has many advantages and allows for great simplicity and flexibility. Of course an dedicated field could be created, but I mostly prefer to do these thing as much as possibly using that approach.
-
I don't think it's possible with a selector to recieve pages that have one specific month (across years). Your solution is the only I can think of. However you could write an helper function to just be able to use $pages->findPeopleBorn(9); to keep template code thin. A module with a hook $this->addHook("Pages::findPeopleBorn",$this,"findPeopleBorn"); which then has a public method findPeopleBorn($event) that returns results would be a good way to do this. See "HelloWorld.module" for example. One way to archive it without going through all users would be to separate day,month,year into their own fields. This would be easy to then query all pages with a specific month via a simple find(selector). Or a custom mysql sql query to recieve the id's and load the pages from that. Assuming the date field is called "birthdate": $tmplID = $templates->get("people")->id; $month = 8; $query = " SELECT field_birthdate.data,field_birthdate.pages_id FROM field_birthdate LEFT JOIN pages ON (field_birthdate.pages_id=pages.id) WHERE (EXTRACT(MONTH FROM field_birthdate.data) = $month) AND pages.status < 2048 AND pages.templates_id=$tmplID ORDER BY pages_id"; $res = $db->query($query); if($res->num_rows){ $ids = array(); while($u = $res->fetch_array()) $ids[] = $u['pages_id']; } $ids = implode("|",$ids); $people = $pages->find("id=$ids"); foreach($people as $p){ echo "<p>$p->title</p>"; }
-
PW can't handle include decision for you. PW doesn't make any decision on templates and logik in front-end, you always have to provide an if-then and best way here is use simple includes for the view. You can specify a template file a page uses when rendering. But not for the page you're on, because it already has a template file your code is in and end in a recursion giving you an memory limit error. But you can do it for a page you're you are recieving from a find/get query and give it a template file before render it. For example: $gallery = $pages->get($id); if($input->urlSegment1 == 'view') { $gallery->template->set("filename","view_full_gallery.php"); $gallery->render(); } else { $gallery->template->set("filename","view_teaser_gallery.php"); $gallery->render(); } So this will render the gallery page with different templates depending on a condition. As you already seem to tried you could change the template file (not the PW template) of a page via a before page render hook.
-
I'm a bit confused by your question, why do you want to post to another url anyway? It's a post to the same page the form lies. If you chose another url for the action you have to have code there to read the post and process it. There's no such thing as post to a template. The code example is for building the form and process it at the same time, hardly ever need to separate that logic, but you could.
-
Cynical answer, yes in the API docs http://processwire.com/api/fieldtypes/ there's all the infos you need. But people don't seem to find it or read it. And in the forums there's tons of. Search google with "site:processwire.com keywords". But I know what you mean, and I also think there's so many snippets hiding in the forums it would be nice to have a wiki like repository or something. But then we started it long time ago http://wiki.processwire.com , just nobody seems to take the time to build it. Also some lonely is trying to make something here http://clintonskakun.com/processwire-docs/
-
What is the error? Possibly u need to turn off output formatting for the user before manipulating. $u->of(false).
-
this request was aborted because it appears to be forged
Soma replied to joshuag's topic in General Support
Nope. But i pefer to use the fields and templates as a start so never ever do it. :-P -
Because they're pages. so same applies. And it's there.. http://processwire.com/api/cheatsheet/?filter=users
-
Its $users like $pages. Forget var dump:-) Also the cheatsheet is your friend ;-) http://processwire.com/api/cheatsheet/
-
this request was aborted because it appears to be forged
Soma replied to joshuag's topic in General Support
Blank profile is done using pw 2.2.0 I think so there could be the problem. However it would take u only little time creating a new one. Or just start with the default install, which is actually very nice start. -
I'm not sure about your term "delete field"? Are you sure you want to delete the "field" and not just empty the value or remove the entry from a repeater list? Because if you are talking about a repeaters fields and you delete one of the fields it has, it will be gone for all entries. If I understand correctly you only want to "remove" an entry in the list (repeater)? Reading here http://processwire.c...ypes/repeaters/ there's no "delete", but there's a remove method to remove and certain entry in a repeater. Also repeaters are "pages" and behave like a pagearray and you can use find(selector) and get(selector) to find entries. So the code would be like this: $name = $pages->get($id)->title; $found = $pages->find('created_users_id='.$user->id.',guests.guest_name='.$name); foreach ($found as $f) { foreach ($f->guests as $g) { if ($g->guest_name == $name) { $f->guests->remove($g); // remove the entry from the repeater $f->save(); // without saving page, nothing will happen } } } Or this maybe $name = $pages->get($id)->title; $found = $pages->find('created_users_id='.$user->id.',guests.guest_name='.$name); foreach ($found as $f) { $entries = $f->guests->find("guest_name=$name"); // do a find on repeater, like with pages foreach ($entries as $entry) { $f->guests->remove($entry); // remove the entry from the repeater $f->save(); // without saving page, nothing will happen } } Or if you are sure there's only 1 page and 1 entry at any time to be found anyway $name = $pages->get($id)->title; $found = $pages->get("created_users_id=$user->id,guests.guest_name=$name"); // get the 1 page if($found) $entry = $found->guests->get("guest_name=$name"); if($entry) { $found->guests->remove($entry); $found->save(); } All written in browser, so not tested.
-
To check if there's really results you can check num_rows if ($results->num_rows) { // outpute the results } else { // no results }
-
Do you want to build a form to edit data on a page or is it on another page? Is it possibly a PW user? So it's not the "page" you're looking at, like in the admin backend edit screen? In this case you could load the edit screen of PW with /processwire/page/edit/?id=$page->id and add a &modal=1. If you load that edit link using fancybox iframe feature you get something like adminbar module. So if you enter /processwire/page/edit/?id=1&modal=1 you'll get the edit form without the layout around. Of course this is only for trusted users, as you could remove the param and edit other things like publish, hidden etc. But it's a nice alternative to edit pages data without leaving the frontend page. But if you are wanting a community user to edit his "profile data", which isn't necessary on the page he's viewing or only part and you will code a form to edit the data he can, you simply make a file with the view profile and for edit profile. In your page template for the profile you then simply include one or the other depending on the url segment. Or make the two views they're own physical page. Kinda obvious it would look like this with segments and include. if(count($input->urlSegments) == 0){ include("view_profile.php"); } else if($input->urlSegment1 == 'edit'){ include("edit_profile.php"); } In a edit template to edit profile user data, I for example do something like this: if($user->isLoggedin() && $user->hasRole('beratung-user')) { // logged in $form = $modules->get("InputfieldForm"); $form->action = "./"; $form->method = "post"; $form->attr("id+name",'profil-form'); $field = $modules->get("InputfieldText"); $field->label = "Last Name"; $field->attr('id+name','last_name'); $field->required = 1; $field->value = $user->last_name; $form->append($field); $field = $modules->get("InputfieldText"); $field->label = "First Name"; $field->attr('id+name','first_name'); $field->required = 1; $field->value = $user->first_name; $form->append($field); $field = $modules->get("InputfieldEmail"); $field->label = "E-Mail"; $field->attr('id+name','email'); $field->required = 1; $field->value = $user->email; $form->append($field); $field = $modules->get("InputfieldText"); $field->label = "Username"; $field->attr('id+name','name'); $field->required = 1; $field->value = $user->name; $form->append($field); $field = $modules->get("InputfieldPassword"); $field->label = "Password"; $field->attr("id+name","pass"); $form->append($field); $submit = $modules->get("InputfieldSubmit"); $submit->attr("value","Save"); $submit->attr("id+name","submit"); $form->append($submit); // process form if($input->post->submit) { $form->processInput($input->post); if(!$form->getErrors()){ $user->of(false); // outputformatting off $user->name = $sanitizer->username($input->post->name); $user->first_name = $sanitizer->text($input->post->first_name); $user->last_name = $sanitizer->text($input->post->last_name); if($input->post->pass; != ''){ $user->pass = $input->post->pass;; } $user->email = $sanitizer->email($input->post->email); $user->save(); $user->of(true); // outputformatting on $session->message("Profile saved"); $session->redirect("./"); // redirect to get rid of double post when refreshing } else { // error message are already added by form->processInput() call } } $out .= $form->render(); } else { $out .= "<p>You don't have permission to view this page.</p>"; } ?> <section class="clearfix"> <h1>Edit your Profile</h1> <?php if(count($notices)) include($config->paths->templates . "inc/notices.inc"); ?> <?php echo $out; ?> </section>
-
It would be a matter of couple php lines to import those data to a repeater or pages. Also everything about repeater you should know is well described here: http://processwire.com/api/fieldtypes/repeaters/
-
in templates you can do $results = $db->query("SELECT * FROM yourtable"); or in modules $results = $this->db->query("SELECT * FROM yourtable");
-
Ops, ok that's a little different then but still same concept. Then you can do something like this? $class = "item"; foreach ($galleries as $gallery) { $status = ''; if ($gallery === $galleries->first()) { $status .= " active"; } $class .= $status; ... Don't worry we all do it wrong from time to time, even if you done it many times