-
Posts
5,008 -
Joined
-
Days Won
333
Everything posted by Robin S
-
Nice work! Must be a good feeling to have such a big task completed and live. I'm always interested to hear how much time goes into larger jobs like this undertaken by a single developer: any idea how long you spent on it? I noticed a couple of minor display issues on the Books page. You can see both in the screenshot below: "Book recommendations" item seems to be missing expected content. Side column layout issue at some device widths. Edit: one more on this page... the "Powered by Goodreads" link is malformed. Again, a really great site.
-
Not in this fieldtype as it stands because it only has a single inputfield. But you can create other fields for the purpose and add them to your template, maybe grouped inside a fieldset together with the Assisted URL field. Text fields for title and rel, and maybe a Select Options field would be good for target.
-
@tpr, another idea/request: if the "permanent delete" option for Page List is checked then there is also an option to permanently delete the page from the Delete tab of Page Edit. Thanks!
-
It requires a couple of steps, but so long as your pages selector doesn't return a huge number of results this should be fairly low impact: $value = 'Foo'; $all_matches = $pages->find("my_table.my_field=$value"); $first_row_matches = $pages->newPageArray(); foreach($all_matches as $match) { if($match->my_table->first()->my_field == $value) $first_row_matches->add($match); }
-
AddHookAfter("save"...) on Page template ==("")
Robin S replied to Mathroth's topic in Module/Plugin Development
Needs the Pages class in there somewhere. Either: public function ready() { if($this->page->template->name == 'TemplateName') { $this->pages->addHookAfter('save', $this, 'syncMobileDE'); } } Or: public function ready() { if($this->page->template->name == 'TemplateName') { $this->addHookAfter('Pages::save', $this, 'syncMobileDE'); } } -
Try Pageimages::add($item)... $user->userimage->add($upload_path . $files[0]);
-
@tpr, I often want to work with system templates. Examples being: Add fields to the user template, and want easy access to the template from the admin menus or without having to set the "Show system templates" filter in the templates list. When editing a field, add that field to the template of a repeater field. Normally to do stuff like this you have to have $config->advanced = true in /site/config.php, but I don't want the risk of messing up the other things that this setting exposes. So I looked at making system templates visible through hooks and came up with this: // Show system templates $this->addHookBefore('ProcessField::buildEditFormInfo', function($event) { // Show system templates in templates list of Edit Field $this->wire('config')->advanced = true; }); $this->addHookBefore('ProcessTemplate::executeNavJSON', function($event) { // Show system templates in admin menu $this->wire('config')->advanced = true; }); $this->addHookAfter('Session::loginSuccess(roles=superuser)', null, function($event) { // Show system templates in templates list unless explicitly hidden $this->wire('session')->set('ProcessTemplateFilterSystem', 1); }); Is this something you think would be a good option to add to AOS?
-
Loading field options into inputfieldSelect
Robin S replied to Marcel Stäheli's topic in API & Templates
To add the 'country' field you can simply do this: $inputfield = $user->getInputfields('country'); $form->add($inputfield); Depending on how many fields in your user template, when building a profile edit form for the frontend it can be easier to define an array of 'ignore' fields and then add all inputfields for the user template that are not in the ignore array. Pretty sure I got this idea from some code by @Soma. // Get the fields from the user template $inputfields = $user->getInputfields(); // Don't include these fields in the form $ignore_fields = [ 'user_name', 'temp_password', 'roles,' ]; // Add the inputfields to the form foreach($inputfields as $inputfield) { if(in_array($inputfield->name, $ignore_fields)) continue; $form->add($inputfield); } -
Just reporting back that for my case this turned out to be very easy using just WireHttp alone and no Oauth client library needed. $http = new WireHttp(); $consumer_key = 'my_key'; $consumer_secret = 'my_secret'; $auth_token = 'my_auth_token'; $auth_token_secret = 'my_auth_token_secret'; $time = time(); $nonce = md5(uniqid(microtime())); // OAuth authorization header $http->setHeader('Authorization', "OAuth oauth_consumer_key=$consumer_key, oauth_token=$auth_token, oauth_version=1.0, oauth_timestamp=$time, oauth_nonce=$nonce, oauth_signature_method=PLAINTEXT, oauth_signature={$consumer_secret}%26{$auth_token_secret}"); // Parameters $params = [ 'member_listing' => '123456', 'rows' => '20', 'photo_size' => 'FullSize', 'return_metadata' => 'false', ]; $params_str = http_build_query($params); // Get JSON response from Trade Me $json = $http->getJSON("https://api.tmsandbox.co.nz/v1/Search/Property/Rental.json?$params_str"); Because of the circumstances of my case I can hardcode $auth_token and $auth_token_secret. But more often with OAuth you would need to get these values in a separate query and store them.
- 1 reply
-
- 4
-
-
Looks mostly good to me. My thoughts... If I'm understanding your code correctly (it would be clearer if you used a separate forum code block for each separate file) I think the code that builds the selector would be better placed in your search template (search.php) rather than in your search-form.php include. I think this would solve some of your concerns, and also allows you to create links to the search results page that don't come via the search form (e.g. suppose you had a page that listed a link for each town to show results for that town). If your search form appears on the search results page you just need to make sure the code that builds the selector is above the search-form.php include so that the whitelist variables have been populated. This part... $townSelectorPart = ""; foreach ($towns as $town) { $townSelectorPart .= $town . "|"; } $townSelectorPart = rtrim($townSelectorPart, "|"); ...could be shortened to... $townSelectorPart = implode('|', $towns); I think it's okay to use an unsanitized GET variable if you are using it only to check if that variable is present.
-
Super-useful video and your command of English is really impressive: you are more articulate than many native speakers! It's very slick what the GraphQL devs have done with the GraphiQL tool - so nice having the documentation explorer right there inside the tool. Thanks for the video, and also a separate thanks for updating the Skyscrapers profile and making the export of that available. Would it be okay to mention your repo of that over in the Skyscrapers Profile thread so people can use it until we have an official profile release by Ryan?
-
Adding a file to Pagefiles and saving to Database
Robin S replied to ethanbeyer's topic in API & Templates
The $field argument supplied to $page->save() must be a field name or field object. But in your example $files is neither of these (it will be a Pagefiles object). -
Cool, thanks @BitPoet.
-
If you have a "one video per page" setup then again you could dynamically generate options using another Hanna tag: get all children of "video pool" that have a video uploaded to them.
-
First time with Markup Regions - no luck getting it to work
Robin S replied to evanmcd's topic in General Support
The following quote from the blog post is useful in understanding how your templates need to be structured in order for Markup Regions to work: So the general rule is: the place where you define your 'original' markup regions (that you will append to, etc, in your template files) needs to have the doctype or <html> element in it, and it needs to be the last piece of markup to be rendered. That's why your markup regions would typically be originally defined in an auto-appended "_main.php" so that it is rendered last, and any markup that you are echoing or outputting in your template files will reference those regions and appear before the doctype/<html> of _main.php. -
I'm working on a module where I iterate over all fields in a template, and wanting to minimise the number of different field value types I need to account for. Is there a way to get the value of a 'single' Page field as a PageArray, so the value of the field is of the same type as a 'multiple' Page field? With single/multiple Image and File fields I can use getUnformatted() to ensure I always get the field value as a WireArray. I thought there might be something similar possible for Page fields.
-
@ottogal, you are right - this module will not cover your way of using HannaCode. But if you only needed to select from videos uploaded to the current page instead of letting the editor choose another page (or alternatively from one page that contains all videos), you could adapt the approach I show in the first post for creating select options from images on the page.
-
$this->addHookBefore('Page::render', function($event) { $page = $event->object; // use whatever condition suits your needs if($page->id == 1234) $page->body = 'blaat'; });
- 10 replies
-
- 1
-
-
- page::render
- render
- (and 4 more)
-
I need to retrieve some data from an external API that uses Oauth 1.0 authentication. This is the first time I've needed to use Oauth so I'm looking for advice. Does PW have any built-in tools that help with retrieving data from an external API and using Oauth? WireHttp maybe? For doing the Oauth stuff is it sensible to use a dedicated library (like OAuth 1.0 Client from thephpleague) or is it easy enough with just the functions built into PHP and/or PW?
- 1 reply
-
- 2
-
-
Thanks for the report @Macrura, fixed with isset() now (no version change). It bugs me a bit that PW doesn't save default values to the module config automatically in the module installation routine. Seems to me that is the whole point of defining a default - so some config value is present if nothing has been set manually.
-
In v0.0.2 I have added a hookable method that supplies the array of tag names for the dropdown menu. You can use an 'after' hook to control what appears in the dropdown. A couple of examples... Define the tags for a given template: $this->addHookAfter('HannaCodeDialog::getDropdownTags', function($event) { $page = $event->arguments('page'); // Show only these tags on pages using the 'basic_page' template if($page->template == 'basic_page') { $event->return = ['some_tag', 'another_tag']; } }); Remove certain tags for a given template: $this->addHookAfter('HannaCodeDialog::getDropdownTags', function($event) { $page = $event->arguments('page'); $tags = $event->return; // Remove these tags on pages using the 'basic_page' template if($page->template == 'basic_page') { $filtered_tags = array_filter($tags, function($tag) { return !in_array($tag, ['some_tag', 'another_tag']); }); $event->return = array_values($filtered_tags); } });
-
That fixes it, thanks.
-
@spacemonkey95 and @ottogal: just an FYI that I released a new Hanna-related module and among the features are a dropdown menu in the CKEditor toolbar for inserting Hanna tags, and the tags may be excluded based on a tag name prefix or the selection of individual excluded tags in the module config.
-
I have had this module sitting in a 95% complete state for a while now and have finally made the push to get it out there. Thanks to @teppo for his Hanna Code Helper module which I referred to and borrowed from during development. http://modules.processwire.com/modules/hanna-code-dialog/ https://github.com/Toutouwai/HannaCodeDialog HannaCodeDialog Provides a number of enhancements for working with Hanna Code tags in CKEditor. The main enhancement is that Hanna tags in a CKEditor field may be double-clicked to edit their attributes using core ProcessWire inputfields in a modal dialog. Requires the Hanna Code module and >= ProcessWire v3.0.0. Installation Install the HannaCodeDialog module using any of the normal methods. For any CKEditor field where you want the "Insert Hanna tag" dropdown menu to appear in the CKEditor toolbar, visit the field settings and add "HannaDropdown" to the "CKEditor Toolbar" settings field. Module configuration Visit the module configuration screen to set any of the following: Exclude prefix: Hanna tags named with this prefix will not appear in the CKEditor toolbar dropdown menu for Hanna tag insertion. Exclude Hanna tags: Hanna tags selected here will not appear in the CKEditor toolbar dropdown menu for Hanna tag insertion. Background colour of tag widgets: you can customise the background colour used for Hanna tags in CKEditor if you like. Dialog width: in pixels Dialog height: in pixels Features Insert tag from toolbar dropdown menu Place the cursor in the CKEditor window where you want to insert your Hanna tag, then select the tag from the "Insert Hanna tag" dropdown. Advanced: if you want to control which tags appear in the dropdown on particular pages or templates you can hook HannaCodeDialog::getDropdownTags. See the forum support thread for examples . Edit tag attributes in modal dialog Insert a tag using the dropdown or double-click an existing tag in the CKEditor window to edit the tag attributes in a modal dialog. Tags are widgets Hanna tags that have been inserted in a CKEditor window are "widgets" - they have a background colour for easy identification, are protected from accidental editing, and can be moved within the text by drag-and-drop. Options for tag attributes may be defined You can define options for a tag attribute so that editors must choose an option rather than type text. This is useful for when only certain strings are valid for an attribute and also has the benefit of avoiding typos. Add a new attribute for the Hanna tag, named the same as the existing attribute you want to add options for, followed by "__options". The options themselves are defined as a string, using a pipe character as a delimiter between options. Example for an existing attribute named "vegetables": vegetables__options=Spinach|Pumpkin|Celery|Tomato|Brussels Sprout|Potato You can define a default for an attribute as normal. Use a pipe delimiter if defining multiple options as the default, for example: vegetables=Tomato|Potato Dynamic options Besides defining static options as above, you can use one Hanna tag to dynamically generate options for another. For instance, you could create a Hanna tag that generates options based on images that have been uploaded to the page, or the titles of children of the page. Your Hanna tag that generates the options should echo a string of options delimited by pipe characters (i.e. the same format as a static options string). You will probably want to name the Hanna tag that generates the options so that it starts with an underscore (or whatever prefix you have configured as the "exclude" prefix in the module config), to avoid it appearing as an insertable tag in the HannaCodeDialog dropdown menu. Example for an existing attribute named "image": image__options=[[_images_on_page]] And the code for the _images_on_page tag: <?php $image_names = array(); $image_fields = $page->fields->find('type=FieldtypeImage')->explode('name'); foreach($image_fields as $image_field) { $image_names = array_unique( array_merge($image_names, $page->$image_field->explode('name') ) ); } echo implode('|', $image_names); Choice of inputfield for attribute You can choose the inputfield that is used for an attribute in the dialog. For text attributes the supported inputfields are text (this is the default inputfield for text attributes so it isn't necessary to specify it if you want it) and textarea. Note: any manual line breaks inside a textarea are removed because these will break the CKEditor tag widget. Inputfields that support the selection of a single option are select (this is the default inputfield for attributes with options so it isn't necessary to specify it if you want it) and radios. Inputfields that support the selection of multiple options are selectmultiple, asmselect and checkboxes. You can also specify a checkbox inputfield - this is not for attributes with defined options but will limit an attribute to an integer value of 1 or 0. The names of the inputfield types are case-insensitive. Example for an existing attribute named "vegetables": vegetables__type=asmselect Descriptions and notes for inputfields You can add a description or notes to an attribute and these will be displayed in the dialog. Example for an existing attribute named "vegetables": vegetables__description=Please select vegetables for your soup. vegetables__notes=Pumpkin and celery is a delicious combination. Notes When creating or editing a Hanna tag you can view a basic cheatsheet outlining the HannaCodeDialog features relating to attributes below the "Attributes" config inputfield. Advanced Define or manipulate options in a hook You can hook HannaCodeDialog::prepareOptions to define or manipulate options for a Hanna tag attribute. Your Hanna tag must include a someattribute__options attribute in order for the hook to fire. The prepareOptions method receives the following arguments that can be used in your hook: options_string Any existing string of options you have set for the attribute attribute_name The name of the attribute the options are for tag_name The name of the Hanna tag page The page being edited If you hook after HannaCodeDialog::prepareOptions then your hook should set $event->return to an array of option values, or an associative array in the form of $value => $label. Build entire dialog form in a hook You can hook after HannaCodeDialog::buildForm to add inputfields to the dialog form. You can define options for the inputfields when you add them. Using a hook like this can be useful if you prefer to configure inputfield type/options/descriptions/notes in your IDE rather than as extra attributes in the Hanna tag settings. It's also useful if you want to use inputfield settings such as showIf. When you add the inputfields you must set both the name and the id of the inputfield to match the attribute name. You only need to set an inputfield value in the hook if you want to force the value - otherwise the current values from the tag are automatically applied. To use this hook you only have to define the essential attributes (the "fields" for the tag) in the Hanna Code settings and then all the other inputfield settings can be set in the hook. Example buildForm() hook The Hanna Code attributes defined for tag "meal" (a default value is defined for "vegetables"): vegetables=Carrot meat cooking_style comments The hook code in /site/ready.php: $wire->addHookAfter('HannaCodeDialog::buildForm', function(HookEvent $event) { // The Hanna tag that is being opened in the dialog $tag_name = $event->arguments(0); // Other arguments if you need them /* @var Page $edited_page */ $edited_page = $event->arguments(1); // The page open in Page Edit $current_attributes = $event->arguments(2); // The current attribute values $default_attributes = $event->arguments(3); // The default attribute values // The form rendered in the dialog /* @var InputfieldForm $form */ $form = $event->return; if($tag_name === 'meal') { $modules = $event->wire('modules'); /* @var InputfieldCheckboxes $f */ $f = $modules->InputfieldCheckboxes; $f->name = 'vegetables'; // Set name to match attribute $f->id = 'vegetables'; // Set id to match attribute $f->label = 'Vegetables'; $f->description = 'Please select some vegetables.'; $f->notes = "If you don't eat your vegetables you can't have any pudding."; $f->addOptions(['Carrot', 'Cabbage', 'Celery'], false); $form->add($f); /* @var InputfieldRadios $f */ $f = $modules->InputfieldRadios; $f->name = 'meat'; $f->id = 'meat'; $f->label = 'Meat'; $f->addOptions(['Pork', 'Beef', 'Chicken', 'Lamb'], false); $form->add($f); /* @var InputfieldSelect $f */ $f = $modules->InputfieldSelect; $f->name = 'cooking_style'; $f->id = 'cooking_style'; $f->label = 'How would you like it cooked?'; $f->addOptions(['Fried', 'Boiled', 'Baked'], false); $form->add($f); /* @var InputfieldText $f */ $f = $modules->InputfieldText; $f->name = 'comments'; $f->id = 'comments'; $f->label = 'Comments for the chef'; $f->showIf = 'cooking_style=Fried'; $form->add($f); } }); Troubleshooting HannaCodeDialog includes and automatically loads the third-party CKEditor plugins Line Utilities and Widget. If you have added these plugins to your CKEditor field already for some purpose and experience problems with HannaCodeDialog try deactivating those plugins from the CKEditor field settings.
-
I don't think there is a setting or hookable method you can use for this. But AdminOnSteroids adds body classes based on the user role, so you could use a bit of custom jQuery to remove the Tree panel toggle button for a role: // remove Tree panel toggle for editor role $('body.role-editor').find('.pw-panel[data-tab-icon="sitemap"]').parent('li').remove();
- 1 reply
-
- 2
-