-
Posts
5,008 -
Joined
-
Days Won
333
Everything posted by Robin S
-
How to render admin page into a variable to create a PDF?
Robin S replied to dotnetic's topic in General Support
I'd say this is the way to go for sure. There aren't that many fieldtypes that require special treatment, and this way you get exactly the markup you want. You can get the inputfield widths used in Page Edit too so the layout is similar. A starting point... $out = ''; $p = $pages(1234); // get the page however you like $fieldgroup = $p->fields; foreach($fieldgroup as $field) { /* @var Field $field */ $field = $fieldgroup->getFieldContext($field); $inputfield = $field->getInputfield($p); $width = $inputfield->columnWidth ?: 100; // getFieldValue() is a function/method you create that returns a string (could be markup) value for $field on $p, depending on the type of $field $value = getFieldValue($p, $field); $out .= "<div class='field-value' style='width: {$width}%'>$value</div>"; } I think it's unlikely that the admin markup is going to render nicely when you convert it to PDF. In my experience the HTML-to-PDF conversion tools don't handle complex layouts well. Plus there is going to be all kinds of markup in Page Edit that won't be relevant to what you want to show in your PDF (tabs, buttons, "Add New" links for Repeaters, etc). If you do want to try HTML-to-PDF conversion for PW's default markup value for fields, or using the Page Edit markup, then here are some avenues to explore. Your mileage may vary as I only tested these quickly. You'll need to include the admin CSS. // Use PW's default markup value for different field types $out = ''; $p = $pages(1234); // get the page however you like foreach($p->fields as $field) { $out .= $p->getMarkup($field->name); } // Get markup for the whole Page Edit form $input->post->id = 1234; // the ID of the page you want $ppe = $modules->ProcessPageEdit; $out = $ppe->execute(); // Get markup for just the Content tab (you can't easily show more than one tab in the PDF anyway) $input->post->id = 1234; // the ID of the page you want $ppe = $modules->ProcessPageEdit; $form = $ppe->buildFormContent(); $out = $form->render(); -
Thanks for the updates Ryan! For the children counts in Page List, would you please consider adding hookable methods that return $numChildren and $numTotal? That would allow the option for devs to add a hook to correct those counts in case some descendant pages are not listable by some roles. Thanks. Also, not sure if this is deliberate but I notice the new child count options don't take effect in the Pages > Tree flyout menu.
-
[BUG] Different output for logged in / logged out users
Robin S replied to Tom.'s topic in General Support
I believe this is because $page->next() is for traversing pages as they appear in the page tree. So when you use it on a repeater page it will refer to the next sibling page in the page tree, in the Repeaters section under the Admin branch. Those pages use a system repeater template that is accessed controlled. Non-superusers don't have access to those pages themselves, they only have access to repeater items via a repeater field value (a RepeaterPageArray). Whether this is a good thing or not has been under debate here: https://github.com/processwire/processwire-issues/issues/183 A better option might be to use WireArray::getNext() on the repeater field value, which will hopefully avoid the access issues for non-superusers. // $value is repeater field value if($value->getNext($item) && $value->getNext($item)->size->value != 'half') -
Interesting. It's based on FieldtypeFieldsetOpen, which likewise creates a database table (as does FieldtypeFieldsetClose). Not sure why these fieldtypes do that considering they don't store data, but it doesn't do any harm that I can see.
-
@bernhard, you can actually remove a few more methods from such a fieldtype - FieldtypeFieldsetOpen is a good one to refer to for a fieldtype that doesn't store anything in the database. A while ago I made a simple runtime-only fieldtype that generates inputfield markup from PHP files in a subfolder within /site/templates/ - sort of like a stripped-back version of RuntimeMarkup without any config fields in admin. It was just intended for use in my own projects and I didn't think it was worth announcing publicly seeing as we already have kongondo's module, but I've moved it to a public repo in case it is interesting for you to take a look at: https://github.com/Toutouwai/FieldtypeRuntimeOnly
-
Exactly that. It's great when you have a big messy spreadsheet and you just want to grab selections of data to add to the Table.
-
Just popping in to say thanks for this awesome module! The "Paste in CSV Data" field saved me a heap of time today.
-
You have two accounts here at the forum? The first post in this topic is from a different user. Usually this kind of page list error is due to some error message (e.g. PHP notice) being returned in the AJAX response used to build the page list instead of the expected JSON data. You can debug by checking the AJAX response in your browser dev tools. It should look like this when it's working normally:
-
Besides the multi-instance thing, Ryan brought to my attention recently another reason to prefer $this->wire('config') or $this->wire()->config over $this->config... If you are doing this inside a class (e.g. a module) then it's less efficient to do $this->config because PW has to first check to see if you have a property or method in the class named config, and only after that go to the $config API variable. With $this->wire('config') or $this->wire()->config there is no uncertainty. Personally I prefer $this->wire()->config over $this->wire('config'), only because it's easier to paste it in or do a find/replace when updating older code, and easier to assign a shortcut to $this->wire()-> in my IDE and have my cursor end up in the right place after I've typed the API variable name. ?
-
Prevent Page to be deleted when it is referenced by another page
Robin S replied to KarlvonKarton's topic in General Support
It's linked to in the GitHub issue that szabesz mentioned, but in case you missed it, there is a hook here for preventing referenced pages from being trashed... ...and from being trashed or directly deleted... -
Unordered List to Pages: action for Admin Actions
Robin S replied to Robin S's topic in Modules/Plugins
v0.1.3 released, with some new features thanks to a request from Adrian. Any override templates specified in the list items will be created if they don't already exist. You can also set allowed parent templates or allowed child templates for a template within a list item. See the readme or the "cheatsheet" field for the syntax. -
I've added support for this in v0.2.0.
-
There is also this: https://modules.processwire.com/modules/fieldtype-select-file/
-
v0.1.1 released - adds an option to automatically derive a label from the template name if a new template is added via the API. Also finally got around to submitting it to the modules directory.
-
I think the problem here is that you are replacing newlines with <br>, but that doesn't make sense for the content you are importing. If your content consists of markup then you don't want newlines to become <br>s because the newlines exist in the markup just for code readablity and aren't something that should result in new HTML tags in the saved field value. If you set the field value directly from $r['textEN'] then it should work.
-
@Bacelo, you can do all of that more efficiently in a single selector string: $termine = $page->children("(standort_reference~=$standort), (standort_alle=1), sort=date, limit=10, date>=today"); https://processwire.com/api/selectors/#or-groups
-
PW has an option to keep a history of pageviews in $session. You use a setting in /site/config.php to define how many history items you want to keep... // Keep the last 10 pageviews in the session history $config->sessionHistory = 10; ...and then get a multi-dimensional array of history data with... $history = $session->getHistory(); You could use this history to build your breadcrumb trail from.
- 3 replies
-
- 6
-
-
- breadcrumbs
- path
-
(and 1 more)
Tagged with:
-
Are you logging in as a non-superuser? If that's not it and you have copy/pasted the hook code then it would be worth checking to see if any invisible characters got pasted which will prevent the code from working. I notice that this forum software has gotten quite bad recently at inserting invisible characters into code blocks - I see these characters in the email notifications I get from the forum. Most reliable thing for short blocks of code from the forum is to retype them yourself in your code editor. Another way is to use a tool that shows hidden characters. When I copy/pasted the hook code above into this online tool this is what I got: If that's still not it then I'm out of ideas, but you can try debugging with Tracy Debugger. Assuming you are developing your site locally, you'll need the "Force guest users into DEVELOPMENT mode on localhost" option checked in order to see the Tracy bar when logged in as a non-superuser. Bar dump $id and $page->template->name to check that these are what the hook is looking for in the conditional. I've modified the hook slightly just to make it clearer how the conditional relates to what you will be seeing in the bar dumps: $wire->addHookAfter('Page::listable', function(HookEvent $event) { // Only for non-superusers if($this->user->isSuperuser()) return; // The ID of the page that Page List is listing children of $id = $this->input->get->int('id'); $page = $event->object; // Dump to Tracy bar bd($id, 'parent page id'); bd($page->template->name, 'template name'); // Don't list pages with certain templates under Home (adjust template names as needed) if($id === 1 && ($page->template->name === 'internal_db' || $page->template->name === 'newsletter')) { $event->return = false; }; });
-
Creating a support topic for this action now that the new actions-as-modules feature has been added to Admin Actions. Unordered List to Pages An action for the Admin Actions module for ProcessWire CMS/CMF. Creates a structure of new pages from an unordered list entered into a CKEditor field. The nesting of further unordered lists within the list will determine the nesting of the created pages. Created pages get a default template that you select, and you can override this default template per list item by specifying a template name between [[ ]] delimiters. This action can be useful to quickly create a page structure; especially so if you are rebuilding an existing non-ProcessWire site that has a Sitemap page that you can copy and paste from. Usage Install the Unordered List to Pages module. Visit the Admin Actions config screen and enable the "Unordered List to Pages" action for the roles who are allowed to use it. Navigate to Admin Actions > Unordered List to Pages and fill out the config fields: Source Enter/paste an unordered list in the Source field. There is a "cheatsheet" field above that explains the syntax you can use to set some template options for each list item. If you want to override the default template for an item you can specify a template name after the page title between double square brackets. If the template doesn't already exist it will be created. Example: Page title [[staff_members]] You can also specify one or more allowed child templates for a template like so: [[staff_members > manager tech_support]]This would create the page using the staff_members template, and set the allowed child templates of staff_members to manager and tech_support. Alternatively you can specify one or more allowed parent templates for a template like so: [[manager < staff_members]] This would create the page using the manager template, and set the allowed parent templates of manager to staff_members. Parent page Select a parent page that the new pages will be created under. Default template Select the default template to use for the new pages. Screenshots Action config: Result: https://github.com/Toutouwai/AdminActionsUnorderedListToPages https://modules.processwire.com/modules/admin-actions-unordered-list-to-pages/
-
I think authors maintaining actions in their own repos is the way to go. I know from past experience that when tinkering around I often do several commits after I think I've done my "final commit" for a version as I spot little errors or think of new ideas. I wouldn't want to have to bother you or me with pull requests for these. Having a list of third-party actions in the readme sounds like a good idea, but I have another idea too. I think it would be cool if we could leverage the power of the modules directory and ProcessWireUpgrade for actions, so users can see when updates are available and easily pull those updates in. So the idea is that each third-party action that extends ProcessAdminActions would have its own "pseudo-module" - a module file containing just the required getModuleInfo() method. So for my action above the module folder would look like this: And ActionUnorderedListToPages.module would consist of this: <?php namespace ProcessWire; class ActionUnorderedListToPages extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Unordered List to Pages', 'description' => 'Creates a structure of new pages from an unordered list.', 'version' => '0.1.0', 'author' => 'Robin Sallis', 'href' => 'https://github.com/Toutouwai/ActionUnorderedListToPages', 'extends' => 'ProcessAdminActions' ); } } ProcessAdminActions would look for third-party actions like this... $third_party_actions = $this->wire('modules')->findByInfo('extends=ProcessAdminActions'); ...and then get the action by looking for an ".action.php" file in the module directory. ProcessAdminActions could hopefully grab the action title/description from getModuleInfo() rather than this needing to be duplicated inside the action file (but no big deal if that wont fly). So this would require coding some extra features in ProcessAdminActions but I think being able to use the modules directory would be really cool. And the exact details of how all this would work is up for discussion of course - this is just me brainstorming here. What do you think? I might be wrong but this sounds like it wouldn't work very reliably. Sitemaps generally just have the URL to the resource and that seems like it would problematic to parse into the desired page structure in many cases: There is no page title in an XML sitemap so pages would have to use the slug name as page title, which may not be that close to the desired title - so potentially requiring a lot of manual fixes later and not making the action much of a time-saver. Many sites don't have the tidy connection between URL and page structure that PW has - worst are ones like /index.php?id=1234&view=detail&foo=bar. I'm not sure what the action would be able to do with this. XML sitemaps often include entries for non-page resources such as PDF files. If you think the XML sitemap idea can work I'm happy to be proved wrong. ? Maybe you want to have a play around with it?
-
An action that I made for my own convenience but that others might find useful too: Unordered List to Pages An action for the Admin Actions module for ProcessWire CMS/CMF. Creates a structure of new pages from an unordered list entered into a CKEditor field. The nesting of further unordered lists within the list will determine the nesting of the created pages. This can be useful to quickly create a page structure; especially so if you are rebuilding an existing non-ProcessWire site that has a Sitemap page that you can copy and paste from. All the created pages get the same template - for any pages that should use a different template you can easily change this as you edit the page to add content, or use the Page Manipulator action for bulk template changes. Usage Install the action by copying the "UnorderedListToPages" folder to /site/templates/AdminActions/, and then visiting the Admin Actions config screen and enabling the "Unordered List to Pages" action for the roles who are allowed to use it. Navigate to Admin Actions > Unordered List to Pages and fill out the config fields: Enter/paste an unordered list in the Source field. Select a parent page that the new pages will be created under. Select the template to use for the new pages. Execute the action. Screenshots Action config: Result: https://github.com/Toutouwai/UnorderedListToPages Update: https://github.com/Toutouwai/AdminActionsUnorderedListToPages This action module now has its own support topic:
-
That's weird - the $wire API variable should be in scope there. Add the ProcessWire namespace to the top of /site/ready.php if it isn't there already. You are running PW 3.x right? And double-check the ready.php file is in the right place, in the /site/ folder and not in /site/templates/ or anything like that (I only mention it because it's happened before ?). Your /site/ready.php file should look like this: <?php namespace ProcessWire; $wire->addHookAfter('Page::listable', function(HookEvent $event) { // Only for non-superusers if($this->user->isSuperuser()) return; // The ID of the page that Page List is listing children of $id = $this->input->get->int('id'); $page = $event->object; // Don't list pages with certain templates under Home (adjust template names as needed) if($id === 1 && ($page->template == 'internal_db' || $page->template == 'newsletter')) { $event->return = false; }; }); Here is more information about /site/ready.php: https://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/#new-core-files-for-site-hooks
-
It's possible your method that tries to get the array is firing before init() has fired. The Module docs say: So __construct() fires earlier. Where you choose populate the array would probably depend on whether you need to get any custom module config at that point. If you don't need the module config then populate the array in __construct(). But init() is early enough for most cases too. An example: <?php namespace ProcessWire; class TestModule extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => "Test Module", 'version' => 1, ); } public $colours = array(); public function init() { $this->colours = array( 'Red', 'Orange', 'Yellow', ); } }
-
Use of special url-protocols in CKEditor Fields
Robin S replied to Andreas Augustin's topic in General Support
When I tested those URLs, I only had to turn off HTML Purifier and the links remained in the field after page save. Leaving ACF on did not affect the links. -
Welcome to the forums. ? The structure of the page tree (Page List) always reflects the path to pages on the front-end. That fact is part of the ProcessWire philosophy that Ryan has talked about somewhere (can't remember where exactly). So you can't have the Home page appear anywhere other than at the root of the page tree. In terms of having a dashboard instead of Page List there are several forum topics that are relevant. A Google search will find them: https://www.google.com/search?q=site:processwire.com+dashboard And here is another approach you can try... 1. Install the AdminOnSteroids module, and use the "Add pages to navigation" feature to add your Internal DB and Newsletter pages as custom nav items. This will add those pages to the Pages menu so that if you click them you'll see only those sections in Page List. 2. Add a hook to /site/ready.php (add the file if it doesn't exist) so that your Internal DB and Newsletter pages do not appear in the main Page List, so they are not confusing to your users. $wire->addHookAfter('Page::listable', function(HookEvent $event) { // Only for non-superusers if($this->user->isSuperuser()) return; // The ID of the page that Page List is listing children of $id = $this->input->get->int('id'); $page = $event->object; // Don't list pages with certain templates under Home (adjust template names as needed) if($id === 1 && ($page->template == 'internal_db' || $page->template == 'newsletter')) { $event->return = false; }; });