Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/14/2015 in all areas

  1. Please, someone kick me in the head, I must be sleeping or something. https://github.com/ryancramerdesign/ProcessWire/issues/1506 I've opened this ticket yesterday, and today it's already resolved. I'm realy impressed by such amazing speed and feedback. Honestly, right now every thing about PW looks too good to be true. I realize that this is sort of "honeymoon" with new software that eventually will end, but oh well.
    8 points
  2. @tired_eyes, everything ends but ProcessWire just stepped in a new era and is not likely to go away soon. The 3.0 step will be a big transition but for building sites (writing templates) it's not going to change anything. I don't know any system that's more consistent and simple to use, yet so powerful. Say your PW journey ends over a year of 5 you've gained so much `ProcessWire` knowledge, you will realise then that you fully mastered the language PHP.
    6 points
  3. In ProcessWire we have Hanna Code and it uses almost the same syntax as in MODX except those are snippets and chunks in one. Hanna code runs from disk, while MODX snippets are eval()'t. (is that a good word ? ) You could also create a page with a footer template and just render that page in your template with $yourpage->render(). After a while you will discover more options to do things, just give your self the time .
    3 points
  4. I ended up using 1st level pages for the main shop: (MAIN SHOP) — news — products — about-us — services — AFFILIATES — — AFFILIATE 1 — — — about-us — — — services — — AFFILIATE 2 — — — about-us — — — services This way the urls are fixed (/products, /services, etc). However, these urls are loading the affiliate's matching pages. Subpage are served using url segments. Internal links would contain the full url, inlcuding the main shop's too, which is overriden using a Page::path hook in the ready.php file. The nice thing is that this change seems fully global, so far I haven't found a link where it failed, including the admin pages. So if one affiliate's editor edit its "about-us" page and click on the "View" tab, it will navigate to "/about-us" instead of "/affiliates/affiliate2/about-us/", which is just fine. On template level I have pre-defined variables for the different levels: - $page - $affiliate (the active one that will be determined by domain name later) - $currentPage (determined by the url segment, if any) I'm really happy so far that I'm using PW for this site. There's still a ton of work to be done but it seems it will work. To be honest I don't know how I would do this without PW, but now I can roll out the very first demo in about a week (including front-end development), which is so cool.
    2 points
  5. At least the design is top notch Why are you looking elsewhere? Looking for challenges?
    2 points
  6. just completed and updated the function in the post above.
    2 points
  7. Many thanks for all the suggestions! My current working solution is using a Pagefield with PageTreeSelect, and as a sidenote: wow! I never have used this fieldtype combination before. I always used ASM-Select. Just fallen in love again with PW. The second element is an injected button, what I have learned recently from a nice and usefull snippet of @Lostkobrakai. The working code is located in the ready.php and uses the PW API. Our pages in the example here uses the PageTreeAddNewChildReverse module, so the sort numbers stored in the DB are very high. (If you wonder why they have such high numbers in the screenshots.) The Pagefield where we select the new neighbour page is named "albumselect". /* moving albumpages programatically in the PageTree */ $wire->addHookAfter("ProcessPageEdit::buildForm", function(HookEvent $event) { $DEBUG = true; $FIELD = 'albumselect'; // change to the name of your Pagefield ! $page = $event->object->getPage(); if (!(bool)$page->fields->get($FIELD)) return; // check if the page includes the submitbutton for our function if (!$page->sortable()) { // check if the page is sortable and the user has the right to sort it $this->warning($this->_("You have not the right to sort this page.")); return; } if ('sort' != $page->parent->template->sortfield && '' != $page->parent->template->sortfield) { $this->warning($this->_("The sortsetting of the parent page does not allow drag and drop. It is set to: {$page->parent->template->sortfield}")); return; } $form = $event->return; $input = wire('input'); $pages = wire('pages'); $i = $num = 0; if ($input->post('hook_move_page_in_pagetree') && $input->post($FIELD)) { $page->of(false); $selectedNeighbour = $pages->get($input->post($FIELD)); #$sortLow = $page->parent->child('include=all')->sort; // the sortnumber of the first page in the tree, top page $sortCur = $page->get('sort'); // the current number of the page we want to move $sortEnd = $selectedNeighbour->getUnformatted('sort'); // the number of the page where we want to sort in the current page if ($DEBUG) my_var_dump(array('sortCur' => $sortCur, 'sortEnd' => $sortEnd), 1); if (0 < $selectedNeighbour->id) { if ($sortCur != $sortEnd) { // has the user selected a real or valid change of position? if ($sortCur < $sortEnd && $sortCur != $sortEnd - 1) { // we want to move this page down in the tree foreach($page->parent->children('include=all') as $p) { $num++; $p->of(false); if ($i++ > 50) { set_time_limit(30); $i = 0; } // just to play save, reset timelimit if ($p->sort == $sortEnd) { // we reached the page on which top we want to place the current one if ($DEBUG) { my_var_dump(array('num' => $num, 'page->sort' => $page->sort, 'result' => $sortEnd - 1, 'sortCur' => $sortCur, 'sortEnd' => $sortEnd, 'break' => true), 1); } else { #$page->setAndSave('sort', $sortEnd - 1, array('quiet' => true)); databaseUpdateSortInPages($page->id, $sortEnd - 1); } break; // we are finished now } if ($sortCur < $p->sort) { // only change sort for pages that are between $sortCur and $sortEnd if ($DEBUG) { my_var_dump(array('num' => $num, 'p->sort' => $p->sort, 'result' => $p->sort - 1, 'sortCur' => $sortCur, 'sortEnd' => $sortEnd), 1); } else { #$p->setAndSave('sort', $p->sort - 1, array('quiet' => true)); databaseUpdateSortInPages($p->id, $p->sort - 1); } } $pages->uncache($p); // free memory } } elseif ($sortCur > $sortEnd || $sortCur == $sortEnd - 1) { // we want to move this page up in the tree foreach($page->parent->children('include=all') as $p) { $num++; $p->of(false); if ($i++ > 50) { set_time_limit(30); $i = 0; } if ($p->sort >= $sortEnd && $p->sort <= $sortCur) { if ($p->sort == $sortCur) { if ($DEBUG) { my_var_dump(array('num' => $num, 'p->sort' => $p->sort, 'result' => $sortEnd, 'sortCur' => $sortCur, 'sortEnd' => $sortEnd, 'break' => true), 1); } else { #$page->setAndSave('sort', $sortEnd, array('quiet' => true)); databaseUpdateSortInPages($page->id, $sortEnd); } break; } else { if ($DEBUG) { my_var_dump(array('num' => $num, 'p->sort' => $p->sort, 'result' => $p->sort + 1, 'sortCur' => $sortCur, 'sortEnd' => $sortEnd), 1); } else { #$p->setAndSave('sort', $p->sort + 1, array('quiet' => true)); databaseUpdateSortInPages($p->id, $p->sort + 1); } } } $pages->uncache($p); } } } } if ($DEBUG) die(); } $button = wire('modules')->get('InputfieldSubmit'); $button->attr('id+name', 'hook_move_page_in_pagetree'); $button->value = __('jetzt einsortieren!'); $button->addClass('ui-priority-secondary'); $form->insertAfter($button, $form->get($FIELD)); }); function databaseUpdateSortInPages($id, $sort) { $sql = "UPDATE pages SET sort = $sort WHERE id = $id"; $query = wire('database')->prepare($sql); $query->execute(); } . . EDIT: Updated the above code. It supports up and down moving now. Also it has a debug function now. (The used function for debug output is in the spoiler beneath) What could be done better: [x] first check if the pages are set to use manually drag/drop sortorder or not. [x] test with direct manipulating DB-tables to improve speed. Currently, on my server, it took up to 35 seconds for iterating over 1250 pages and saving a new sortvalue for each of them. But this only happens if we move it from one end to the other (first place to last place). If we move a page 150 places, there will be only changed 150 pages in DB. This tooks around 4 seconds here. EDIT 2: Updated the code and included @Lostkobrakais idea to check for the PagetreeField on every page, and not on templatenames etc. This way we can add/remove the functionality to every templates we like, just by adding/removing the Pagefield to them, without altering the hook-function. (In our case the pagefield is called 'albumselect'). EDIT 3: Updated the code. Now it doesn't alter the modified time and modified user-id anymore. Before the change, it altered it of each page that changes the sort value! Also the execution time is much faster now. It only takes 3 seconds on my server to move it 1200 pages down or up. (Before using direct DB-access, it took 35 seconds)
    2 points
  8. [[!ProcessWire? &var=`Stable, fast, powerful, consistent and makes you smile.`]] And doesn't use silly snippets
    2 points
  9. Hello there! I'd love to publish my first ProcessWire module. Please let me know if you have any thoughts regarding the quality, documentation or new features you would like to see. See Github page: https://github.com/MartinMuzatko/TextformatterAutoAnchor/ ProcessWire Module: http://modules.processwire.com/modules/textformatter-auto-anchor/ TextformatterAutoAnchor Automatically add anchors and IDs to Headings What is it doing? This Textformatter adds an id attribute to every heading with a slug of the text. Intended for easily creating linkable sections. Demo Currently it is used at http://www.happy-css.com AutoAnchor in action: http://happy-css.com/lessons/riotjs/reusable-components/ Preview can be seen on Github Configurable Variables Heading Selector Determine which headings you want to have the ID + anchor Use a regex-like range or list, e.g.: 2-6 or 346. Anchor Class Your css classes that are attached to the anchor link. Anchor Content The text for your anchor. If you prefer an icon, you could also use HTML for example. What are the Alternatives? There are existing tools like Anchorific JS but its dependency is jQuery. I love to have an alternative that is PHP only. Known issues Anchors are placed in front of the text. This could be a future configurable setting. The slug is also not configurable yet, currently it is lowercased and space is replaced with hyphens/dashes
    1 point
  10. This is already available within the RTE, I think the same functionality should be brought through to the Image field (note: I am not asking for a media manager )
    1 point
  11. Hi Mike, I think the checkbox would be a great addition. This would make it easier for a newbie to Jumplinks be able to just dive in and get things done. I am for this update!
    1 point
  12. I was about to say, that you could add the page field via the hook as well, but I think it's actually quite nice to just look if the page field is part of a page and enhance it automatically. So one doesn't have to touch the hooks code after setting the fields name once.
    1 point
  13. What Martin said two posts above - for folks looking for some familiarity moving from MODx, the Hanna Code module is definitely your friend as its really powerful and you can use these codes inside any textarea field that you have set to parse Hanna Codes.
    1 point
  14. Thanks, seems like a good approach. Was unsure at first whether the "id" value in the JSON export needed to be incremented when duplicating for import, but after testing it looks like PW ignores the id value on import and assigns a new id, so no need to worry about that.
    1 point
  15. Just as a follow-up on this: In a private discussion with Jeff last month, I noted that this scenario will be accomodated in the next version. However, if there are more Jumplinks users bumping into this issue, then I would want to make it part of 1.5. In the discussion, I mentioned there would either be a checkbox in the entity editor that allows you to make query strings optional, or that we could use square parenthises to mark them as optional, like this: bioh[?gclid={token:any}]. After a little thought on the matter, I think it may be better to use the checkbox approach for query strings. However, I think the behaviour should be somewhat different in that it would let you choose to "ignore the query string in source" and, if that is selected, "append original query string to destination". Thoughts? In light of the square parenthises idea, I also have plans to make parameters optional, like so: {?title}
    1 point
  16. For your "typical example" of "the contact info in footer area", you can, for example, just: create a Contact information page (that is hidden), insert <?=$pages->get('/contact-info/')->body?> wherever you want in _foot.php, or elsewhere. That's it. The content editor edits the body field of the Contact information page. There's no need for a template for this page normally. If you define (in _init.php, for example): $contact_info = $pages->get('/contact-info/')->body, you just have to use $contact_info wherever you want. It could be anything of course. Not just a CKEditor textarea body field.
    1 point
  17. @ Lance O. - No problem! I love Jumplinks and have used ProcessWire for tons of client projects! Have faith in it!
    1 point
  18. It looks like setting up the Source URL with the additional code works. (It doesn't look like we need to add the additional code to the page url.) Thank you for your quick response! Client is happy and has restored faith in PW and Jumplinks.
    1 point
  19. You need to go into your GA account and change the Urls to the new Urls or you need to do this: http://www.website.com/bioh? gclid ={id:any} Redirects to http://www.website.com/biohealth?gclid ={id:any}
    1 point
  20. Olá a todos, I've been updating the translation for a project (22 files in processwire 2.6.14. There is more files to come but main ones are there). I thought it could help someone. How can I share this translation with the comunity?
    1 point
  21. ok i thought there was an easy way like almost always in pw but wouldn't it be relatively easy to create a hook to update all sort fields in the database? quite similar to the sortPages method: https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Process/ProcessPageSort.module#L101
    1 point
  22. Had something like this once (not in PW) where I updated the integer sort field to be 100, 200, 300... Then to move item X to be just after item Y you simply give it Y's sort value plus an offset. Use offset of 1 the first time and increment it each time. A negative offset can be used for inserting before. You need a function to normalize the sort values when you are done or after a large number of moves but that's easy enough to do.
    1 point
  23. Hi, and welcome to the forums! The ProcessWire eco-system is active. Ryan Cramer, the creator, is continuously adding new features to PW (on the dev branch) and fixing bugs as he goes along. The community here is small, but active and very helpful. The Modules Directory is also active, with some interesting modules popping up on a regular basis. As mentioned above, PW3 will be Composer-ready, with namespace support. Many here are quite excited about PW3. Version 2.7 is just around the corner (maybe this week), and contains several great updates in comparison to the current 2.6.1 stable. So yes, I recommend the jump.
    1 point
  24. There is a new development release of Processwire every week that you can download. The upcoming version 3 (currently in alpha) will allow for composer support and lots of other things. Its a good time to get involved. I made the switch about 6 months ago and I haven't looked back. I feel I have only just scratched the surface with what this system could potentially do.
    1 point
  25. Ryan could be asked to abstract ProcessPageSort::execute out a bit, so the sorting logic is also usable without faking the ajax data coming from ProcessPageList.
    1 point
  26. Nice ideas, but the doing the save new sorting like an "insertAfter" is the tricky part...
    1 point
  27. I would also go with lostkobrakai's suggestion and create a pagefield to choose the new "top" page. You don't have to look up sort numbers and remember them. Easy and built in scalability due to ajax pagination!
    1 point
  28. Maybe not as convinient, but if you are comfortable in editing json, you can export a text field with built-in PW field export feature, paste the generated code to text editor, duplicate it as many times as you want, edit nearly all the field's properties and import it back into your site.
    1 point
  29. Hi Forum, I recently had a chat with a friend who was introduced to PW by me. He said: "brilliant cms, poor documentation." His comment makes me think about the cheatsheet: While we see new API methods introduced at a very fast pace, the cheatsheet doesn't seem to keep up. That's sad, because it's such a good resource. So, how can I (as a user with very limited PHP skills) help to update the cheatsheet? Is somebody skilled willing to team up with me - as kind of a supervisor - for the update tasks? Or are there any plans on behalf of the team to update the cheatsheet? Thanks!
    1 point
  30. On my side, i tested some methods for add resized or watermarked images to variations for admin panel : If i change your suffix and if i use variation name like ProcessWire (width x height) : // From $suffix = "-pim2-{$suffix}"; // To $suffix = ".pim2.{$suffix}"; // And making watermarking by use variation like ProcessWire // Watermark from original $dImage = $image->pim2Load("{$image->width}x{$image->height}")->watermarkLogo($wmPath, 'c', '2')->pimSave(); // Create medium size from original with watermark $mImg = $image->pim2Load("1130x500")->resize(1130, 500)->watermarkLogo($wmPath, 'c', '2')->pimSave(); // Use medium size for resize (will be watermarked making only resize) $mImg = $mImg->size(750, 300); Created files on disk : Here created variations : Original Size Watermarked Medium Size Watermarked I am not displaying original image. Displaying watermarked and sized images. Like this if i delete images from admin panel delete image and variations, clean work. Now the problem is file sizes as you see on my screen shot. Order : Original Image - Watermarked from Original image - Resized from watermarked original image Edited: File sizes screenshot added.
    1 point
  31. I'll spend a little snippet to render a nice admin table in such kinds of dashboard.... //lets's show some last events //rootpage of articles is XXXX // Find some pages $events = $pages->find("template=event,check_active=0,limit=5,sort=event_start_date,sort=event_start_time"); $table = $modules->get("MarkupAdminDataTable"); $table->headerRow( ["Title", "Created", "User"] ); $table->setSortable(false); $table->action(array( 'New Event' => $config->urls->admin . 'page/add/?parent_id=XXXX', 'All Events' => $config->urls->admin . 'page/events/', )); foreach($events as $page){ $data = array( // Values with a sting key are converter to a link: title => link $page->title => $config->urls->admin."page/edit/?id=".$page->id, date("F j, Y", $page->created), $page->createdUser->full_name ); $table->row($data); } // $table->footerRow( $someArray ); echo '<div class="someclass">'; ">'; echo $table->render(); echo '</div>'; renders something like this: have fun
    1 point
  32. Elastic Search itself was okay. Here's what I found. Timeout while indexing: The module's code for indexing all pages does a find and I'd assumed it would make use of the template whitelist value from module configuration but it didn't. It finds lots of pages, then skips the ones which should not be indexed. I have thousands of simple pages (containers for images) which don't need to be found by this selector. Now I'm using the whitelist to build a more specific selector. May have to break this up into multiple finds when I have more content. In checkForRebuildSearchData() $arr = $this->getAllowedTemplates(); $str = (count($arr)) ? ' template='.implode('|', $arr).',' : ''; $pages = $this->pages->find("id!=2, id!=7, has_parent!=2, has_parent!=7, template!=admin,$str include=all"); The other thing that became obvious pretty quickly is that the Textareas (with an s) fieldtype was not handled. Adding a function and a line to use it in getAllContentForPage() took care of that. protected function getTextareasTypeAsContent($value) { $values = array(); foreach ($value as $name=>$value) { $values[$name] = $value; } return $values; } ... elseif ($type instanceof FieldtypeTextareas) $value = $this->getTextareasTypeAsContent($value); I've confirmed that it is picking up changes when I edit pages. Too early for opinions on effectiveness of Elastic Search itself.
    1 point
  33. ProcessWire uses quite basic RBAC system and it probably just didn't feel necessary to dive further into this. Some of the basics: Each user has one or more roles; "guest" is always assumed and required, even for non-logged-in users (i.e. visitors) Each role is a named collection of one or more permissions; page-view (as you noted before) is always assumed and required and only displayed because, well, it's there (that's actually supposed to be helpful; you don't have to guess which permissions this role might have, what you see is what you get) Permissions are just permissions, there's nothing really magical about them; for the most part they're just Pages with special purpose Each Page uses a Template and each Template has access settings, where you can define which roles have access to the basic actions on Pages using said template: view, edit, create and add children One important thing to note here is that an user having a role with page-edit (or page-view) permission won't instantly allow that user to edit / view all pages but it is a prerequisite for giving this kind of access at Template level (via access settings). Template level access settings are just one use case for the access control system in ProcessWire; it actually goes a lot further and is much more versatile than that. (Admittedly this part does sometimes cause confusion and thus it might be worthwhile to document it more clearly.) Programmatically managing and/or checking for roles/permissions is explained in the docs. If you want to check if user has specific permission, whether that's built-in permission or one you've added yourself, it goes like this: $john = $users->get("johndoe"); if ($john->hasPermission("read-the-docs")) { echo "Sure thing, go ahead: http://processwire.com/api/"; } Cheatsheet also provides basic info on most (if not all) actions you can perform on/with users, roles and permissions. If you use $pages->find(), it should already only return pages that current user has view access to (unless you add "include=all"), so I'm not entirely sure what you're referring to in your last comment. Pages don't have roles, they have a Template, and that Template has access settings. If current user doesn't (via one of her roles) have access to view that Page, it won't be returned by $pages->find() either. Note: $pages->get() is different from $pages->find(), as it assumes you really want that one, specific Page. It always returns the Page (if it exists) without considering permissions.
    1 point
×
×
  • Create New...