Jump to content

ryan

Administrators
  • Posts

    17,100
  • Joined

  • Days Won

    1,642

Everything posted by ryan

  1. It's looking great!
  2. That was fast! Glad it's working. For the next step (keeping it modal), I pushed a couple updates to GitHub today to aid in doing that (made a few more things hookable). So make sure you've got the latest commit. Now we want to hook into a couple more things to modify the form URL and redirect URL, like you did by editing ProcessPageEdit, but we want to do it in a way that doesn't require changing anything in the core. So here is the full skeleton module code from before, but with the addition of two new hooks. Note that I didn't add as many comments to the new stuff, because I have to go pick up my daughter from school, so please reply with any questions: <?php class AdminBar extends WireData implements Module { /** * This is where you define some basic info about your module. * * See /wire/core/Module.php for definitions of all these. * */ public static function getModuleInfo() { return array( 'title' => 'Admin Bar', 'summary' => '[summary of your module], by apeisa', 'href' => 'http://processwire.com/talk/index.php/topic,56.0.html', 'version' => 100, 'permanent' => false, 'autoload' => true, 'singular' => true, ); } /** * Initialize the module and setup hooks * * The init method of a module is called right after ProcessWire is bootstrapped, when all * API vars are ready. Whereas the __construct() is called DURING bootstrap, so the init() * method is a better place to attach hooks to API vars. * * In this method, we'll use an 'after' hook since we want to modify the output of the * rendered page template. * * Note also that the 'Class::method' syntax means it hooks into ALL Page instances. * The syntax for hooking to a single instance would be: * $page->addHookAfter('render', $this, 'pageRender'); * * Also note that there isn't actually a Page::render method, it was instead added by * another module (wire/modules/PageRender.module). Not that it matters here, but just * wanted to mention in case you look in the Page class and don't see a render method. * */ public function init() { // modify the output of a page render, adding some markup to support the adminbar $this->addHookAfter('Page::render', $this, 'pageRender'); // hook before forms are rendered, so that we can modify the form's "action" attribute $this->addHookBefore('InputfieldForm::render', $this, 'formRender'); // hook before a redirect occurs, os we can modify the redirect URL $this->session->addHookBefore('redirect', $this, 'sessionRedirect'); } /** * Hook called when a page is rendered * * The method name used here does not matter, it just has to be consistent with the name you provided * when creating the hook. * * This method is given an $event object of type HookEvent. To see what's in that, see this file: * /wire/core/HookEvent.php (it's very short and simple) * */ public function pageRender($event) { // $event->object always has the object instance that resulted in this call $page = $event->object; // if the page isn't editable, or if it's using the admin template, abort. if(!$page->editable() || $page->template == 'admin') return; // find the location of this module for linking css and js files $url = $this->config->urls->AdminBar . "AdminBar"; // the css and js links we're going to add $out = "\n\t<link rel='stylesheet' type='text/css' href='$url.css' />" . "\n\t<script type='text/javascript' src='$url.js'></script>" . "\n</head>"; // modify the value returned by $page->render() to include our css and js files $event->return = str_ireplace('</head>', $out, $event->return); } /** * Hook to take place before forms are rendered * * We check if there is a 'modal' get var set, and if so, we add it to the form's action attribute * */ public function formRender($event) { if(!$this->input->get->modal) return; $form = $event->object; $action = $form->attr('action'); $action .= (strpos($action, '?') !== false ? '&' : '?') . "modal=1"; $form->attr('action', $action); } /** * Hook to take place right before a redirect occurs * * We intercept the redirect URL and modify it to add 'modal=1' to the query string * */ public function sessionRedirect($event) { if(!$this->page || $this->page->template != 'admin') return; if(!$this->input->get->modal) return; $url = $event->arguments(0); if(preg_match('/[?&]modal=/', $url)) return; $url .= (count($this->input->get) ? '&' : '?') . "modal=1"; $event->arguments(0, $url); } } Lastly, I should probably have the core look for a modal attribute and keep it going when it finds it (because this has use elsewhere), but I thought this was a really good example of how to implement a module, so figured we would start here.
  3. Another easy way you can upgrade from the ZIP is to unzip the archive, and copy the /site/ dir from your existing installation into it. Then delete /site-default/ and /install.php, and rename htaccess.txt to .htaccess. Upload to your web server or development environment (replacing your existing installation), and you are good to go.
  4. Great! glad that worked. Let me know how it goes...
  5. Very likely this could be developed with add on modules relatively easily. For instance, I have another ProcessWire site that is integrated into Drupal's user system, and implementation was fairly straightforward (at least on the ProcessWire side!). We use this for providing access to members-only articles, whereby a user makes a subscription purchase in UberCart/Drupal and then they gain a time-limited role in ProcessWire that gives them access to those members-only articles. Granted, this could have been done in just Drupal, but the site is broader than that and better suited for ProcessWire in all other respects. So that's one example of user integration. Can you give me an example from the PHPBB side, of what additional functions you would want to provide to the PHPBB user in ProcessWire? That will help me to better understand the goal, so that I can make suggestions on implementation.
  6. That makes sense, and is worth looking at more. On the back end, fields are actually assigned to fieldgroups, and fieldgroups to templates (rather than just fields and templates like it appears on the front end). Technically, a given fieldgroup can be attached to multiple templates, though that option is not visible on the front end (to keep things as simple as possible). But fieldgroups would represent the partials that you are talking about, which are already in the system and API accessible.
  7. Looking in the code, the error actually makes sense, and I located what the problem was right away. What I don't understand is why it's never turned up before. But I am glad you found it, because it does appear to be a bug in PW2's module installer. You'll want to update your /wire/core/Modules.php: https://github.com/ryancramerdesign/ProcessWire/commit/4cf59bb7ea49a0d6449361285c177c0dd93182bd#diff-0 Or here is the full file: https://github.com/ryancramerdesign/ProcessWire/raw/4cf59bb7ea49a0d6449361285c177c0dd93182bd/wire/core/Modules.php
  8. Strange... Can you confirm that this is the error that you when when clicking the "install" button in the Modules section? This sounds like a MySQL error. Can you tell me what version you are running? Also, I am preparing an updated /wire/core/Modules.php for you, but just wanted to confirm about when the error occurs. Thanks, Ryan
  9. Hi Peter, You need to make use of a Page reference field type instead of a Text field type. When you create a Page reference, it will use a group of pages (based on your criteria) as select options. You can choose for it to be either a regular select, select multiple, or other input type after you create the field. (I need to make a screencast to demonstrate this fieldtype). This is one way that ProcessWire is a little different from other systems, and it might seem a little odd at first, but once you try it, the benefits become obvious and hard to beat. Ryan
  10. Actually you don't need to create the fields in the DB (at least, if it's working right). It should let you store anything and it'll encode it into the existing 'data' field. But if you aren't in a hurry to get this functionality, I agree that it may be better to wait since there are some changes in order for the users system. Regardless, I don't plan to change the methods of access (api) unless I have to.
  11. Apeisa: Let me know if that module skeleton worked for you. It occurred to me last night that it might not work unless you are running a very recent version of PW2. If not, make sure you have the latest (I added upgrade instructions to the FAQ section in the forum).
  12. The two should run alongside each other just fine. For instance, this forum (SMF) is running alongside ProcessWire, and I just modified the default SMF theme to match the rest of the site. But "integration" can mean many things, so I wanted to find out more specifically what you mean in this case?
  13. I would except that it's not mine to open source (it was paid work for a client). In addition, it was done in PW1, which is quite different. However, it would actually be easier to do in PW2. If it helps, the fieldtype was based on what was done in FieldtypeFile. But give me a little time, and we'll come up with something much better specific to this need.
  14. ProcessWire upgrades are easy because everything unique to your site is contained under the /site/ directory. That directory is not part of the ProcessWire source, so you just replace everything else, and leave your /site/ directory as it is. Following are instructions on how to do this. If you find an UPGRADE.txt file in the new version of ProcessWire, you should give those instructions authority over these. However, these instructions outline how the majority of ProcessWire upgrades are performed. Please note: these instructions do not apply to a 2.0 -> 2.1 upgrade. For instructions on how to perform that upgrade, please see this thread: http://processwire.com/talk/index.php/topic,583.0.html Upgrading ProcessWire from the ZIP file 1. Download the latest version of ProcessWire from the downloads page at GitHub and click the "Download ZIP" button: https://github.com/ryancramerdesign/ProcessWire/archives/master 2. Extract the ZIP file somewhere temporary (I usually extract on my desktop). 3. Replace the following files from your existing installation with the new versions found in the ZIP you extracted. If you want to be able to revert back to the old version, backup any files you replace first. Replace: /wire/ with the new version Replace: /index.php with the new version Replace: /.htaccess with the new version (rename htaccess.txt from the ZIP to .htaccess) Your site is now upgraded. Test that everything works as it should. Upgrading ProcessWire using Git & GitHub: If you originally installed from the source at GitHub, you can upgrade to the latest version of ProcessWire easily by using git pull. cd /your/processwire/installation/ git pull All files related to your specific site are contained in the /site/ dir, which is not part of the source files on GitHub, so it should remain untouched through the git pull (though it doesn't hurt to back it up). Your site is now upgraded, but you'll want to finalize it by doing a little housekeeping. You will find that git pull added some files that weren't there before. Here's what you should do with them: Delete: /install.php Delete: /site-default/ Rename: /htaccess.txt => .htaccess The above steps are optional if you are upgrading a non-production/development server. Since I git pull regularly, I just leave these files in place so that I don't have to delete them every upgrade. In addition, the .htaccess file rarely changes through upgrades. While optional on a local development server (that isn't accessible from outside), on a production server, you absolutely need to perform these steps. Your site is now upgraded. Test that everything works as it should.
  15. Another option is to build a custom fieldtype for the data you need it to hold. With the project I'm working on now, they needed a multi-column pricing table with any number of rows. So the easiest solution was to just build a custom Fieldtype module for the client. But it sounds like this matrix-type configurable module might solve, or at-least reduce, the need for that type of custom module.
  16. Sounds like a good way to put together the slideshow, and it looks good too!
  17. Adam is right that you can do that part now if you want. But that's an undocumented thing, and I haven't actually tried it (just built it with that intention). If you do it, and find that it doesn't work for any reason, let me know and I'll rush an update to fix it.
  18. Awesome screencast! This looks incredibly useful, so cool to see. I'm limited on time for the moment, so just wanted to quickly follow up with the starter module. When I made this, I wasn't thinking about the admin side of it, where you edited ProcessPageEdit.module. I need to take a closer look tomorrow and update the starter module code to hook into that too. But here is something to get started. It's actually very short, but I loaded it with comments that I thought would help, so it looks a lot longer than it actually is. Place this in: /site/modules/AdminBar/AdminBar.module <?php class AdminBar extends WireData implements Module { /** * This is where you define some basic info about your module. * * See /wire/core/Module.php for definitions of all these. * */ public static function getModuleInfo() { return array( 'title' => 'Admin Bar', 'summary' => '[summary of your module], by apeisa', 'href' => 'http://processwire.com/talk/index.php/topic,56.0.html', 'version' => 100, 'permanent' => false, 'autoload' => true, 'singular' => true, ); } /** * Initialize the module and setup hooks * * The init method of a module is called right after ProcessWire is bootstrapped, when all * API vars are ready. Whereas the __construct() is called DURING bootstrap, so the init() * method is a better place to attach hooks to API vars. * * In this method, we'll use an 'after' hook since we want to modify the output of the * rendered page template. * * Note also that the 'Class::method' syntax means it hooks into ALL Page instances. * The syntax for hooking to a single instance would be: * $page->addHookAfter('render', $this, 'pageRender'); * * Also note that there isn't actually a Page::render method, it was instead added by * another module (wire/modules/PageRender.module). Not that it matters here, but just * wanted to mention in case you look in the Page class and don't see a render method. * */ public function init() { $this->addHookAfter('Page::render', $this, "pageRender"); } /** * Hook called when a page is rendered * * The method name used here does not matter, it just has to be consistent with the name you provided * when creating the hook. * * This method is given an $event object of type HookEvent. To see what's in that, see this file: * /wire/core/HookEvent.php (it's very short and simple) * */ public function pageRender($event) { // $event->object always has the object instance that resulted in this call $page = $event->object; // if the page isn't editable, or if it's using the admin template, abort. if(!$page->editable() || $page->template == 'admin') return; // find the location of this module for linking css and js files $url = $this->config->urls->AdminBar . "AdminBar"; // the css and js links we're going to add $out = "\n\t<link rel='stylesheet' type='text/css' href='$url.css' />" . "\n\t<script type='text/javascript' src='$url.js'></script>" . "\n</head>"; // modify the value returned by $page->render() to include our css and js files $event->return = str_ireplace('</head>', $out, $event->return); } } Also you will want to create: /site/modules/AdminBar/AdminBar.css /site/modules/AdminBar/AdminBar.js Thanks for what you are doing here, nice work and great screencast! I will work on expanding this starter example.
  19. I think I may not totally follow what you are doing here, but if I understand correctly, these two things may help: 1. Assuming that slideshow_ref is a page reference field, it should actually be a Page object. The reason it appears to be returning the ID is because that's the typecast string value of a Page object. However, it's actually a Page object Just like $slide is. So there is no need for you to run a separate $pages->get(), because you've already got it. You can just do $slide->slideshow_ref->url. 2. While not applicable in this case, I wanted to explain why Pages may be typecast as strings that return the ID. The reason for this is so that you can use them in selectors. So lets say that you wanted to find all pages that referenced the current page in their slideshow_ref field: $pages->find("slideshow_ref=$page"); Or all other pages (except the current) using the slideshow template that had the same slideshow_ref as the current page: $pages->find("template=slideshow, slideshow_ref={$page->slideshow_ref}, id!=$page"); I don't know if these are useful, but just wanted to use them as examples.
  20. I'll be happy to get you started with a "blank" module that you can build it on top of. What I recommend is that we hook into the Page::render method, grab it's output, and insert your js and css markup file links right before a page's closing </head> tag. That way, when someone installs the module, it'll just start working without them having to do anything on their own. Of course there will be those that want to control the placement of those things, so I'll show you how to make that configurable. The PHP code that is in your .inc will become the module code. Let me know if this sounds like a good plan to you, and I'll follow up with posts showing you how. There are definitely merits to inline editing, depending on the site. I view the needs of page viewing and page editing as fundamentally different, and prefer to have an interface that is designed for one or the other (though the 'overlay', like in Drupal, and in your example, is a nice compromise). But there are many cases where it is really handy to be able to edit inline, if the site design supports it. As an example, I like to make moderated comment approval inline, so that I can just click "approve" or "spam" while viewing the comments (though Akismet mostly does that for me now). There are plenty of other cases, and I'm betting that Aloha Editor will provide some good opportunities. I think you'll find ProcessWire works well when you want something to be editable inline. On the front end, you would just need to make sure that the page is editable before including the inline editors, i.e. if($page->editable()) { ... }. Then you'll need for your template, include or module to look for when they've clicked 'save', i.e. <?php if($input->post->submit_save && $page->editable()) { // turn off runtime formatters (like entities, markdown, date formats, etc). $page->setOutputFormatting(false); // go through all the submitted fields and set those that are applicable foreach($input->post as $field => $value) { if($page->fields->has($field)) $page->set($field, $value); } // if the above resulted in a change, then save the page if($page->isChanged()) $page->save(); // turn output formatting back on so it's in the proper state for viewing $page->setOutputFormatting(true); } Note that if the "save" button is just attached to individual fields, and you'll only be saving one field at a time (possibly ajax driven), then you may want to just save the field rather than the whole page, i.e. $page->save('field name');
  21. Looks like I forgot to update this before, but wanted to mention that this module is now included in the current ProcessWire distribution (and has been for a little while).
  22. This will be possible. Actually, the plan is to change users to be derived from pages and the "user" template will be a system admin template that you can add/modify fields to like any other. Likewise, you'll be able to get/find/manipulate users using the pages functions. The existing $users and $user objects will be mapped to the pages/page API variables. This is the reason why the users, roles and permissions system is barebones in ProcessWire right now ... I wanted to put most of the time into pages, since other systems will be derived from it.
  23. You are right the system would definitely support it pretty easily. The challenge would just be in making it configurable with any fields, and supporting a matrix display... most fieldtypes assume they aren't width limited. In addition, making the individual components of the fieldtype searchable/selectable with the API. But these things are already partially worked out.
  24. This looks awesome, thanks for your work with this! Are you interested in bundling either of these as a module for other people to use? Let me know and I can add a modules section to the download page, as well as assist with any help you need making it a module or adding hooks, etc. I agree re: drupal7 modal, it was a great improvement. The modal var in PW2 is specific to things like the image editing popup and link selector popup (currently used with TinyMCE Fieldtype). It basically just turns off the branding (as you saw). Not sure that's what we would want in this case (?), but perhaps something similar with more minimal branding? Thanks, Ryan
  25. Hi Mike, Good idea. There are definitely plans to do that. Right now you should be able to add fields as you see fit to any $user object, and it should save them in the 'data' field in the users table. (granted I haven't tested this, but it was the intention, though I may need to double check that part is actually working). But you don't see fields for them on the back end (yet). So you can set them with the API but not the admin interface. The plan is to make the users fields configurable like a template, where you can add whatever fields you want. We're not there yet, but just wanted to mention that's the goal. Thanks, Ryan
×
×
  • Create New...