Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/09/2022 in all areas

  1. You've stumbled upon a concept that is, admittedly, a little obscure. The Fieldgroup class comments explain what Fieldgroups are all about, and it boils down to this: Fieldgroups are something that most users don't need to concern themselves with, but technically there's always a fieldgroup behind a template — fields don't belong directly to template, but rather to a fieldgroup, which in turn may be used by one or more templates. Multiple templates using one fieldgroup is, though, pretty rare — I don't think I've ever had that need myself ? All the examples I've seen so far have created a Fieldgroup and then applied it to a Template. If there's a way to create template with fields without creating a fieldgroup to hold said fields, I'm not aware of it (or can't remember it right now — to be honest creating templates via API is not something I do often). No. RockMigrations can make things easier and provide you with many useful tools, but it's not required by any means. If you just need to create a few templates and fields in a module, I personally feel that it's probably overkill to add a dependency to a third party module for that task alone. (Though it could be quite helpful in the future in case you also want to keep those templates/fields in sync with new versions of your module.) I would recommend opening a request for (additional) documentation at https://github.com/processwire/processwire-requests. In my opinion you have a valid point when it comes to fieldgroups — creating templates with fields (and fieldgroups) via API could be more clearly documented. As for "many other things", I don't know what those things would be, but if you can think of some then by all means open a request for those as well. Based on your latest message it seems that you've already solved this — nice! ?
    3 points
  2. Big thanks to @Pixrael for being my first github sponsor ? This is exciting and I really appreciate the appreciation ?
    2 points
  3. In this post we cover the details of a new module (ProcessLanguageFieldExportImport) that enables export and import capabilities for multi-language fields in ProcessWire— https://processwire.com/blog/posts/language-field-export-import/
    1 point
  4. Markup CKEditor (for Form Builder) An inputfield for displaying markup editable via CKEditor. The module is intended for use with the Form Builder module. Allows blocks of static text to be included within a form, which can be edited in the form settings using CKEditor. Screenshots Usage Install the Markup CKEditor module. In the Form Builder module settings, add "MarkupCKEditor" to "Inputfield types to use with FormBuilder". In your form settings, add a new field of type "Markup CKEditor". Enter the text you want to show in this field using "Markup Text" on the "Details" tab. Configuration In the module config you can set items for the CKEditor toolbar that will apply to all Markup CKEditor fields. If you want to insert images in your markup field then add "Image" to the toolbar items to enable the standard CKEditor image plugin. The ProcessWire image plugin is not usable because in a FormBuilder form there is no page to store images in. Advanced There is a InputfieldMarkupCKEditor::ckeReady hookable method for users who want to do advanced customisation of the CKEditor inputfield. It receives three arguments: The InputfieldCKEditor object The form as a FormBuilderForm object The field as a FormBuilderField object Example $wire->addHookAfter('InputfieldMarkupCKEditor::ckeReady', function(HookEvent $event) { /** @var InputfieldCKEditor $cke */ $cke = $event->arguments(0); /** @var FormBuilderForm */ $form = $event->arguments(1); /** @var FormBuilderField $field */ $field = $event->arguments(2); if($form->name === 'test_form' && $field->name === 'my_cke_markup_field') { $cke->contentsCss = '/site/templates/MarkupCKEditor/contents.css'; $cke->stylesSet = 'ckstyles:/site/templates/MarkupCKEditor/ckstyles.js'; } }); http://modules.processwire.com/modules/inputfield-markup-ckeditor/ https://github.com/Toutouwai/InputfieldMarkupCKEditor
    1 point
  5. Ah yes I forgot about make use of the config.php (or init.php) ..... thanks for pointing me there, will try that too. The paths that I declared in the _init.php ..... I simply declared them again on top of my hanna php code and now my hanna code is working in my ckeditor field So either way what will work I mark the question as solved. Note - did you guys know you can render a hanna code directly in a template like this: $hanna = $modules->get('TextformatterHannaCode'); echo $hanna->render("[[my_hanna_snippet]]"); https://processwire.com/talk/topic/14141-outputting-a-hanna-code-via-the-api-in-a-template/ Hanna Code is actually a powerful option.
    1 point
  6. Great new module! Love it! I would also love to extend this module (or have a similar one) to export / import translations for fields' labels / descriptions / notes with per template override support + templates labels. That would make the translation workflow more complete and easy for sites with many languages. @ryan, doesn't your customer accidentally have this need too? ?
    1 point
  7. For my module I need a couple of templates and fields. These templates don't use a corresponding php template file because they don't need to be rendered in the frontend. The pages using these templates and fields are admin area only. I have another module which extends the Process-class that would list the contents of these pages in a table, but that's not relevant here I guess. Here's the full code so far… class Kiosk extends WireData implements Module, ConfigurableModule { public static function getModuleinfo() { return [ 'title' => 'Kiosk', 'summary' => 'Checkout System', 'author' => 'FRUID', 'version' => 1, ]; } public function ___install() { $fields = wire('fields'); $templates = wire('templates'); $fieldgroups = wire('fieldgroups'); // FIELDS if(!$fields->get('custom_order_id')) : $custom_order_id = new Field(); // int or text $custom_order_id->type = $this->modules->get("FieldtypeInteger"); $custom_order_id->title = 'Custom Order ID'; $custom_order_id->name = wire('sanitizer')->pageName($custom_order_id->title, true); $custom_order_id->label = 'Order ID'; $custom_order_id->tags = 'kiosk'; $custom_order_id->save(); endif; if(!$fields->get('custom_order_products')) : $custom_order_products = new Field(); $custom_order_products->type = $this->modules->get("FieldtypeTextarea"); $custom_order_products->title = 'Custom Order Products'; $custom_order_products->name = wire('sanitizer')->pageName($custom_order_products->title, true); $custom_order_products->label = 'Products'; // $custom_order_products->derefAsPage = 1; // $custom_order_products->parent_id = $this->user->parent->id; // $custom_order_products->labelFieldName = 'custom_order_products'; // $custom_order_products->inputfield = 'InputfieldSelect'; // $custom_order_products->required = 1; $custom_order_products->tags = 'kiosk'; $custom_order_products->save(); endif; if(!$fields->get('custom_order_customer_name')) : $custom_order_customer_name = new Field(); // text $custom_order_customer_name->type = $this->modules->get("FieldtypeText"); $custom_order_customer_name->title = 'Custom Order Customer Name'; $custom_order_customer_name->name = wire('sanitizer')->pageName($custom_order_customer_name->title, true); $custom_order_customer_name->label = 'Customer Name'; $custom_order_customer_name->tags = 'kiosk'; $custom_order_customer_name->save(); endif; if(!$fields->get('custom_order_customer_address')) : $custom_order_customer_address = new Field(); // text $custom_order_customer_address->type = $this->modules->get("FieldtypeTextarea"); $custom_order_customer_address->title = 'Custom Order Customer Address'; $custom_order_customer_address->name = wire('sanitizer')->pageName($custom_order_customer_address->title, true); $custom_order_customer_address->label = 'Customer Address'; $custom_order_customer_address->tags = 'kiosk'; $custom_order_customer_address->save(); endif; if(!$fields->get('custom_order_customer_emailaddress')) : $custom_order_customer_emailaddress = new Field(); // email $custom_order_customer_emailaddress->type = $this->modules->get("FieldtypeEmail"); $custom_order_customer_emailaddress->title = 'Custom Order Customer Emailaddress'; $custom_order_customer_emailaddress->name = wire('sanitizer')->pageName($custom_order_customer_emailaddress->title, true); $custom_order_customer_emailaddress->label = 'Customer Email Address'; $custom_order_customer_emailaddress->tags = 'kiosk'; $custom_order_customer_emailaddress->save(); endif; if(!$fields->get('custom_order_shipping')) : $custom_order_shipping = new Field(); // shipping $custom_order_shipping->type = $this->modules->get("FieldtypeText"); $custom_order_shipping->title = 'Custom Order Shipping'; $custom_order_shipping->name = wire('sanitizer')->pageName($custom_order_shipping->title, true); $custom_order_shipping->label = 'Shipping'; $custom_order_shipping->tags = 'kiosk'; $custom_order_shipping->save(); endif; if(!$fields->get('custom_order_total_taxes')) : $custom_order_totalTaxes = new Field(); // totaltaxes $custom_order_totalTaxes->type = $this->modules->get("FieldtypeText"); $custom_order_totalTaxes->title = 'Custom Order Total Taxes'; $custom_order_totalTaxes->name = wire('sanitizer')->pageName($custom_order_totalTaxes->title, true); $custom_order_totalTaxes->label = 'Total Taxes'; $custom_order_totalTaxes->tags = 'kiosk'; $custom_order_totalTaxes->save(); endif; if(!$fields->get('custom_order_total_and_shipping')) : $custom_order_totalAndShipping = new Field(); // Total and Shipping $custom_order_totalAndShipping->type = $this->modules->get("FieldtypeText"); $custom_order_totalAndShipping->title = 'Custom Order Total and Shipping'; $custom_order_totalAndShipping->name = wire('sanitizer')->pageName($custom_order_totalAndShipping->title, true); $custom_order_totalAndShipping->label = 'Total and Shipping'; $custom_order_totalAndShipping->tags = 'kiosk'; $custom_order_totalAndShipping->save(); endif; if(!$fields->get('custom_order_status')) : $custom_order_status = new Field(); // order status $custom_order_status->type = $this->modules->get("FieldtypeText"); $custom_order_status->title = 'Custom Order Status'; $custom_order_status->name = wire('sanitizer')->pageName($custom_order_status->title, true); $custom_order_status->label = 'Order Status'; $custom_order_status->tags = 'kiosk'; $custom_order_status->save(); endif; // FIELDGROUPS if(!$fieldgroups->get('fieldgroup_custom_orders')) : $fieldgroup_custom_orders = new Fieldgroup(); $fieldgroup_custom_orders->name = 'fieldgroup_custom_orders'; $fieldgroup_custom_orders->add($this->fields->get('title')); $fieldgroup_custom_orders->save(); $this->message('creating fieldgroup fieldgroup_custom_orders'); endif; if(!$fieldgroups->get('fieldgroup_custom_order')) : $fieldgroup_custom_order = new Fieldgroup(); $fieldgroup_custom_order->name = 'fieldgroup_custom_order'; $fieldgroup_custom_order->add($this->fields->get('title')); $fieldgroup_custom_order->add($custom_order_id); $fieldgroup_custom_order->add($custom_order_products); $fieldgroup_custom_order->add($custom_order_customer_name); $fieldgroup_custom_order->add($custom_order_customer_address); $fieldgroup_custom_order->add($custom_order_customer_emailaddress); $fieldgroup_custom_order->add($custom_order_shipping); $fieldgroup_custom_order->add($custom_order_totalTaxes); $fieldgroup_custom_order->add($custom_order_totalAndShipping); $fieldgroup_custom_order->add($custom_order_status); $fieldgroup_custom_order->save(); endif; // TEMPLATES if(!$templates->get('template_custom_orders')) : $template_custom_orders = new Template(); $template_custom_orders->name = 'template_custom_orders'; $template_custom_orders->fieldgroup = $fieldgroup_custom_orders; $template_custom_orders->pageLabelField = 'title'; $template_custom_orders->tags = 'kiosk'; $template_custom_orders->save(); endif; if(!$templates->get('template_custom_order')) : $template_custom_order = new Template(); $template_custom_order->name = 'template_custom_order'; $template_custom_order->fieldgroup = $fieldgroup_custom_order; $template_custom_order->pageLabelField = 'title'; $template_custom_order->parentTemplates = array($template_custom_orders->id); $template_custom_order->noChildren = 1; $template_custom_order->tags = 'kiosk'; $template_custom_order->save(); endif; $template_custom_orders->childrenTemplates = array($template_custom_order->id); $template_custom_orders->save(); $parent = wire('pages')->get('/admin/page/'); if ($parent->hasChildren('name=custom_orders') == false) : $c = new Page(); $c->parent = $parent; $template = templates()->get('template_custom_orders'); $c->template = $template; $c->title = 'Custom Orders'; $c->name = 'custom_orders'; $c->save(); endif; } /** * Optional method called when the module is uninstalled * * This method undoes anything that the install() method did. * For instance, remove installed DB tables, files, etc. * */ public function createCustomOrder() { // TODO } public function ___uninstall() { $fields = wire('fields'); $fieldgroups = wire('fieldgroups'); $templates = wire('templates'); $custom_order_pages = wire('pages')->find('template=template_custom_orders|template_custom_order')->count(); // if ($custom_order_pages > 0) // throw new WireException("There are pages using custom-order-templates. Remove those first before uninstall"); foreach($custom_order_pages as $custom_order_page){ $custom_order_page->delete(); } if($fields->get('custom_order_id')) : foreach ($fields->get('custom_order_id')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_products')) : foreach ($fields->get('custom_order_products')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_customer_name')) : foreach ($fields->get('custom_order_customer_name')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_customer_address')) : foreach ($fields->get('custom_order_customer_address')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_customer_emailaddress')) : foreach ($fields->get('custom_order_customer_emailaddress')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_id')) $fields->delete($fields->get('custom_order_id')); if($fields->get('custom_order_products')) $fields->delete($fields->get('custom_order_products')); if($fields->get('custom_order_customer_name')) $fields->delete($fields->get('custom_order_customer_name')); if($fields->get('custom_order_customer_address')) $fields->delete($fields->get('custom_order_customer_address')); if($fields->get('custom_order_customer_emailaddress')) $fields->delete($fields->get('custom_order_customer_emailaddress')); if($fields->get('custom_order_shipping')) $fields->delete($fields->get('custom_order_shipping')); if($fields->get('custom_order_total_taxes')) $fields->delete($fields->get('custom_order_total_taxes')); if($fields->get('custom_order_status')) $fields->delete($fields->get('custom_order_status')); if($templates->get('template_custom_orders')) $templates->delete($templates->get('template_custom_orders')); if($templates->get('template_custom_order')) $templates->delete($templates->get('template_custom_order')); } }
    1 point
  8. Big thanks also to @elabx, really great! I'll stop posting about new sponsors now but I still appreciate your contributions!! ?
    1 point
  9. I've worked with a commercial product lately and all I could do was writing an e-mail to the support-team and then wait over a week to get a response. The PW-forum is not the worst option if one is needing help imho ?
    1 point
  10. A template has an assigned fieldgroup and a fieldgroup holds all the fields. In the PW GUI it looks like you are attaching fields to the template, but you are actually attaching them to the fieldgroup. You could simply use RockMigrations for that tasks... The main reason why I made it public is so that others can use it to easily build modules with it using the far easier syntax compared to doing those things with the default API (as you have realised).
    1 point
  11. So... just made room for playing with RockFrontend and stumbled into this: Not really a deal breaker (the missing requirement) yet that message looks weird and out of place.
    1 point
  12. Brilliant! Since i am involved in multilanguage projects most of the time, this will become very handy. And i use/like the combo fieldtype a lot. So it would be great to see the module supports this fieldtype!
    1 point
  13. Find Merge Adds a Pages::findMerge() method that allows multiple PageFinder selectors to be merged into an efficient paginated set of results. This can be useful when you need more sophisticated sorting of results than what would be possible using only the sort value in a single $pages->find(). Details $results = $pages->findMerge($selectors, $options); $selectors is required and must be an array of selectors. Each selector can be in string format or array format. The findMerge() method will loop over the selectors in the order supplied, adding matching pages to the final results. $options is an optional associative array of options. limit (int) Limit for pagination. start (int) Manually override the start value rather than have it be automatically calculated from the current page number. excludeExisting (bool) Whether or not to exclude pages in each selector that have already been matched by a previous selector. Default is true. keepFirst (bool) When excludeExisting is false then a page might match more than one selector in the supplied array. But each page can only appear once in the results and if keepFirst is true then the page will appear in its earliest position in the results, whereas if keepFirst is false it will appear in its latest position in the results. Default is true. As a shortcut you can supply an integer as the second argument and it will be treated as the limit for pagination. Basic usage For most use cases only a limit will be needed for the $options argument. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $results = $pages->findMerge($selectors, 10); if($results->count) { echo "<p>Showing results {$results->getPaginationString()}</p>"; echo "<ul>"; foreach($results as $result) { echo "<li><a href='$result->url'>$result->title</a></li>"; } echo "</ul>"; echo $results->renderPager(); } Advanced usage The following notes are only relevant to rare cases and most users can safely skip this section. In the demo example the colour page Yellow will potentially match both the 1st selector and the 4th selector. Because of this the excludeExisting and keepFirst options will have an effect on the results. excludeExisting option false Note that the 4th selector asks for 3 colour pages (limit=3). By default excludeExisting is true, which means that when the 4th selector is processed it is interpreted as saying "find 3 colour pages in reverse alphabetical order that have not already been matched in an earlier selector". We can see that there are 3 pages in the results from that selector: Violet, Red, Orange. But if excludeExisting is set to false then the results are different. The matches of the 1st selector (Yellow, Yellow Warbler) are not excluded from consideration by the 4th selector (the 4th selector matches will be Yellow, Violet, Red), and because each page can only appear once in the results this means that the 4th selector ends up only adding 2 more pages to the results. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $options = [ 'limit' => 10, 'excludeExisting' => false, ]; $results = $pages->findMerge($selectors, $options); keepFirst option false As described above, the Yellow page potentially matches both the 1st and 4th selector. By default Yellow will appear in its earliest position within the results, i.e. the position resulting from it being matched by the 1st selector. But if keepFirst is set to false (and excludeExisting is false) then it will appear in its latest position within the results, i.e. the position resulting from it being matched by the 4th selector. $selectors = [ 'title%=yellow', // title contains "yellow" 'title^=z', // title starts with "z" 'title=elephant', // title equals "elephant" 'template=colour, sort=-title, limit=3', // 3 colours in reverse alphabetical order 'template=country, sort=title, limit=40', // 40 countries in alphabetical order ]; $options = [ 'limit' => 10, 'excludeExisting' => false, 'keepFirst' => false, ]; $results = $pages->findMerge($selectors, $options); keepFirst has no effect when excludeExisting is true. https://github.com/Toutouwai/FindMerge https://processwire.com/modules/find-merge/
    1 point
×
×
  • Create New...