Jump to content

Robin S

Members
  • Posts

    5,039
  • Joined

  • Days Won

    340

Everything posted by Robin S

  1. I took a quick look at it. The gist of it is that you would set the width of #tracyConsoleContainer with... width: calc(100% - 380px) !important; ...where 380px is whatever the width of #tracySnippetsContainer should be - there is something not quite right there currently, because the snippets container gets a width from an inline style that is narrower than its contents (which overflow). Also this rule... #tracy-debug fieldset { all: initial !important; ... ...would need to be overridden for the console/snippets panels with... width:100% !important; I don't mind it being there permanently myself. I have a wide enough screen that the Ace window is never so narrow that I'd want extra width by collapsing the sidebar. But maybe some people who work on smaller screens would appreciate that.
  2. I'm loving this! On the Console and Snippets panel it seems that only vertical resizing is possible - horizontal resizing there would be handy.
  3. Here's an example with a single "sounds_like" field containing both metaphone and soundex data. This is better I think. In /site/ready.php: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if(!$page->id || !$page->template->hasField('sounds_like')) return; $sounds_like = ''; $words = explode(' ', $page->title); // Get the individual words of field(s) foreach($words as $word) { if(strlen($word) < 3) continue; // Ignore short words $sounds_like .= metaphone($word) . ' ' . soundex($word) . ' '; } $page->sounds_like = $sounds_like; } In search template file: // $q is the sanitized search string $words = explode(' ', $q); $selector = ''; foreach($words as $word) { if(strlen($word) < 3) continue; // Ignore short words $selector .= 'sounds_like~=' . metaphone($word) . '|' . soundex($word) . ', '; } $results = $pages->find($selector);
  4. A different approach which occurred to me is saving sounds-like data to hidden fields on a page and then searching those fields. This allows for other sounds-like algorithms such as metaphone, and allows for "contains" searches rather than only "equals" searches. Notes on the code that follows: You would create hidden fields "metaphones" and "soundex" and then add those to templates as needed. In the example I just save sounds-like data for the title field, but you could include other fields also. Using Double Metaphone would give more accurate results, but I just used metaphone in the example for simplicity. In the search code I am only searching the sounds-like data, but in the real world you would include other fields in the selector also as the "normal" part of the search. In /site/ready.php: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if(!$page->id || !($page->template->hasField('metaphones') && $page->template->hasField('soundex'))) return; $metaphones = ''; $soundex = ''; $words = explode(' ', $page->title); // Get the individual words of field(s) foreach($words as $word) { if(strlen($word) < 3) continue; // Ignore short words $metaphones .= metaphone($word) . ' '; $soundex .= soundex($word) . ' '; } $page->metaphones = $metaphones; $page->soundex = $soundex; }); In search template file: // $q is the sanitized search string $words = explode(' ', $q); $metaphones = ''; $soundex = ''; foreach($words as $word) { if(strlen($word) < 3) continue; // Ignore short words $metaphones .= metaphone($word) . ' '; $soundex .= soundex($word) . ' '; } $selector = "(metaphones~=$metaphones), "; $selector .= "(soundex~=$soundex)"; $results = $pages->find($selector); This allows matching a page title of "The quick brown fox jumps over the lazy dog" by search strings "offer took" and "quiz fogs" thanks to the differences between metaphone and soundex. Don't expect too much from it though - I found plenty of soundalike words that didn't match. The general principle could be expanded with other algorithms, and it would be cool to enhance this by allowing for mixed matches - for example, where in a two word search one word matches metaphone and the second word matches soundex. Edit: on that last point, a simple way would be to use just a single hidden field for both the metaphone and soundex data. The data from those two algorithms is sufficiently different that unwanted matches wouldn't happen. But if other algorithms were added you'd have to check to make sure the data from one algorithm wouldn't be confused with that of another.
  5. Thanks for the new Buster feature! I'm sure you're right here, but some popular performance rating tools such as GTmetrix will deduct points for query strings on static assets, so that might be a reason to prefer filename versioning if clients will be evaluating the website with those tools.
  6. I don't know anything about translations because where I live there is no demand for multi-language websites. I'm sure someone will help you with specifics for that soon. But as some general advice, you'll find that any development problem becomes a lot less confusing and frustrating as soon as you install Tracy Debugger and learn how the basic bardump works. Then you can start dumping variables in your template files, includes and functions and that way find out where your problem lies. I can testify that it's very empowering and greatly reduces feelings of hopelessness.
  7. Welcome @MikeM! Probably not telling you something you don't already know: the project may be simple conceptually, but it won't be a simple development task. You'll need to work with an experienced developer in order to get a good result with this project. PW is an excellent platform to use for just about any web project, and considering where you are posting this you'll probably find lots of people here who will tell you the same thing. But to be honest, there are many platforms that could be used successfully for this project - in reality the success is more likely to come down to the experience and skill of the developer you hire than the platform used. So seeing as you won't be building the site yourself, your task is really to evaluate developers rather than evaluate ProcessWire. That sounds unusual to me - I haven't heard of people developing one site just to serve as an example for another site they want developed. More typical I think is to use a wireframing tool to show the flow of interactions. This helps you clarify to yourself how the website will work and also helps communicate your intentions to the developer. The wireframe could also demonstrate the design if you wanted that, using a tool such as Invision. Here are some links to a few popular wireframing apps if you want to look at that approach instead: https://www.invisionapp.com/ https://www.mockflow.com/ https://wireframe.cc/
  8. Hi @teppo, The Version Control module is preventing the red asterisk from appearing in the header of required fields. The relevant admin CSS is: .InputfieldStateRequired>.InputfieldHeader:first-child:after { content: ' *'; color: #C00C19; } The addition of the field-revisions div interferes with this.
  9. See here:
  10. I was running quite a recent version (only a few weeks old) but not the very latest. Upgrading to the latest has reduced the number of times the textformatter is called, going from four times down to two times. This is not including any field usage in the template file (i.e. I don't get the field value in my template file, so without the Request Info panel active the textformatter isn't called at all). So it's quite an improvement, but still being called one time more often than I would expect. This is the textformatter I'm using for testing: <?php namespace ProcessWire; class TextformatterTest extends Textformatter implements Module { public static function getModuleInfo() { return array( 'title' => 'Textformatter Test', 'version' => '1', 'summary' => 'Testing', ); } public function formatValue(Page $page, Field $field, &$value) { bd('formatValue'); } } The rest of the setup is basically a clean installation of the blank profile. I can definitely live with it as is, but I'll PM you login details for the test site in case you're interested in investigating.
  11. Hi @adrian, I was doing some testing with a textformatter module and was wondering why the formatValue() method was firing so often, even when my template file does not get the field with the textformatter applied. I traced it back to the Request Info panel - when this panel is active the textformatter formatValue() method fires four times (not including any usages of the field in the template file). I see that the panel shows the value of each field in the template in the "Field List & Values" section, but I would have thought this would only account for one firing. Just wondering if something in that panel is getting the field values more often than necessary and could be optimised perhaps?
  12. Not sure if that was a reply to my comment, but Adrian's idea isn't working when I test it with sort settings applied to the parent page or template. I think it would have to be something like this: $parent = $this->editedPage->parent; if($parent->id) { $sort = $parent->template->sortfield ?: $parent->sortfield; } else { $sort = 'sort'; } $first = $this->editedPage->siblings("sort=$sort, limit=1")->first(); $last = $this->editedPage->siblings("sort=-$sort, limit=1")->first(); Getting a single page could be simplified with findOne(), but not sure if you care about supporting < PW 3.0.3 scratch that
  13. What I meant is that they have to learn how to use the core link dialog regardless because I'm sure they'll need to create non-file links, and then they have to also learn a different method if using this module for file links. Glad you have it working how you like. This module isn't likely to get many updates now that it is merged into AOS, but bear in mind if you do see an update available you will need to either avoid updating or reapply your changes to the updated module files.
  14. I have a feeling this won't work where a sort setting has been defined on the parent page or template. When that is done the sort property of the child pages does not change, so doing a reverse sort on that property would result in the wrong order.
  15. @Arcturus, this module's functionality has been merged into AdminOnSteroids. If you are a user of that module it might be better to post your request in the support thread for AOS. If you're not an AOS user then I guess I could make a config option to reverse the click/Alt-click behaviour. Let me know. I'm not keen to go down this road. There are a large number of attributes a link can potentially have and I don't want to try and support them all. This module is intended as a time-saving tool for power-users who are tasked with loading/editing large amounts of content - I have in mind the superuser who must do an initial loading of content supplied by a client. The module isn't intended to be a full replacement of the PW link dialog. For anything beyond what this module provides I suggest you use the link dialog, or perhaps a textformatter module to apply link attributes like target in a systematic way. TBH, if my clients were 60+ and not all that computer literate I would have them stick to the core link dialog so they don't have to learn something new. Edit: you can also add a target attribute to internal file links via a simple piece of jQuery on the front-end: // Add target attribute to internal file links $('a[href^="/site/assets/files/"]').attr('target', '_blank');
  16. For any field that references a page, the syntax to access and search content in the referenced page is the same. You use dot syntax in the form page_reference_field_name.field_name. This applies equally to Page Reference, PageTable and Repeater / Repeater Matrix field types. So if you use a Page Reference field called "social_networks" that contains pages for Facebook, Twitter and LinkedIn, and those pages contain a "body" field that you want to search, your selector would be: social_networks.body%=foo This will match the page that contains the social_network field rather than the referenced pages. So exactly what you are wanting to do.
  17. Yep, sounds good.
  18. You'll know more about this than me, but my understanding is that what is available in a dump from __debugInfo() depends on what the developer of the class makes available in the method. So if that method in a class was quite limited in what it made available (either intentionally or not intentionally) then the Tracy user potentially misses out on a lot of relevant information. To give a silly example, if I do this in a class... public function __debugInfo() { return ['Nothing to see here.']; } ...then dumping an instance of it will be useless. It looks like most of the __debugInfo() work is done in the dedicated WireDebugInfo class. If you think that Ryan has covered everything that anyone could ever need here then I guess shorter/tidier is better. But if you have doubts I'd rather get all the data as per the status quo than be wondering about what might have been overlooked.
  19. Is your page unpublished? InputfieldPassword is set to required on unpublished pages regardless of what you might have chosen in the field settings - see here. Probably only @ryan could tell you why this is so. You can work around the issue with a hook in /site/ready.php: // You may need to modify "pass" to whatever your password field is named $wire->addHookBefore('Field(name=pass)::getInputfield', function(HookEvent $event) { $page = $event->arguments(0); $field = $event->object; // Do some test on $page and/or $field to identify the cases where the password field should not be required // Then... $field->required = false; });
  20. Thanks for the heads up - I've fixed that. I don't think it's strange. The href property in getModuleInfo() is optional so getting any link is like a bonus - Ryan rarely uses it in his modules for example. If a developer does choose to use the href property then the guidelines are "URL to more information about the module" - I think the GitHub readme satisfies that guideline quite well. The online repository is the primary home of the module - the module directory listing just pulls the readme from the repo. Also, at the time I'm filling out getModuleInfo() the repo URL is the only one that exists. The module doesn't have a directory page or support thread at that point, and some modules never will, so using the repo URL keeps things consistent across all my modules.
  21. The method @LostKobrakai mentions above gives you a clue about how you can make a simple function for the purpose... // Get the page from a path which might include URL segments function getPage($path) { $page = wire('pages')->get("path=$path"); if($page->id) return $page; // If the path matches a page return that $pieces = explode('/', $path); // Break the path into pieces while(!$page->id) { // Until a page is matched... array_pop($pieces); // Pop off the last piece (a URL segment) $path = implode('/', $pieces); // Make a path from the remaining pieces $page = wire('pages')->get("path=$path"); // Try and get a page at that path } return $page; // Return a matching page or a NullPage if no match } If you wanted to get the URL segments from the path it would be easy to modify the function to return those also.
  22. You won't be able to use $log->save() for the reason @alxndre mentioned, and you won't be able to use the admin log viewer because a) it uses new lines to identify each log entry so therefore one entry cannot contain more than one line, and b) it entity encodes HTML for security reasons. But you can use PHP functions like error_log() or file_put_contents() to create your own log file (create the "custom-logs" folder first). $text = date("Y-m-d H:i:s") . "\nHello, how \nare you?\n\n"; // your text, include newlines if needed error_log($text, 3, $config->paths->assets . "custom-logs/mail.txt")
  23. I prefer the responsive embed method... ...and this applies a class to a containing div element.
  24. Browsing to the already selected item gets to be a pain, but thankfully the AdminOnSteroids module has an enhancement that lets you clear the selection more easily.
  25. Those two things contradict each other somewhat. If you are creating a new custom fieldtype then there won't be any existing field data until you create your fieldtype module and start using it in pages. There is the Events fieldtype and inputfield which was created specifically as a proof-of-concept for developers to learn from. But it extends FieldtypeMulti (each field instance saves/shows multiple repeated items) so that might not suit what you are wanting to do. I don't think Ryan made a similar proof-of-concept for a straight Fieldtype. But in a way all the Fieldtype modules in the core and in the modules directory are a proof-of-concept - find a fieldtype that is broadly similar to what you want to do and check out (borrow from ) the code. Also, the documentation for the Fieldtype class will be useful. Perhaps if you describe exactly what you want the fieldtype/inputfield to do people can give you more suggestions.
×
×
  • Create New...