Jump to content

gornycreative

Members
  • Posts

    351
  • Joined

  • Last visited

  • Days Won

    4

Everything posted by gornycreative

  1. This fieldtype has been released and is awaiting approval. I changed the angle input to be an integer entry. I did pull together a strategy for building instances within repeaters. I'll do a writeup of the design pattern as a brief tutorial, as I think until we have a proper set of event handlers for repeater actions/AJAX etc. this is a way to build out a field that requires javascript libraries that is repeater compatible. I feel pretty happy with the end result. It is a fun toy to play with if you have never really explored CSS gradients.
  2. I've seen it come up in the past for sure. Worth having a discussion. I mean, even just an on-page array of booleans that state if a field is loaded on the page would be something, but I agree with this: There are classes on page that indicate this for repeaters. InputfieldRepeaterItem InputfieldStateCollapsed <- class gets applied to LI element for closed repeater item InputfieldRepeaterItem InputfieldStateWasCollapsed <- class gets applied to LI once a repeater item is opened. Further, this gets applied once the AJAX content is loaded. The same applies to repeatermatrix - InputfieldRepeaterMatrixItem gets added to the above. For the immediate need I think what I am going to do is: populate a jsConfig array key with field instance names e.g. field_name, repeater_field_name2300 and a 'loaded' flag run an interval that looks for the target field I need to instantiate, looks for the wasCollapsed state and check for the target field. once it is found in the DOM, create the instance and set the field flag to true, and when all the flags are true break out of the interval. It's sloppy, I hate using intervals to poll the page but my hope is that if someone is working with repeaters they are going to want to dig into new items pretty quickly anyway.
  3. For your goals: $files->getCSV() - https://processwire.com/api/ref/wire-file-tools/get-c-s-v/ Images are a little trickier but if you know where they are stored on the server there's just a little post processing required. https://processwire.com/modules/process-page-field-select-creator/ - then populate the child template with fields you need editing As said above, turn off formatting, then you can iterate through using $pages->findRaw() and implode(), etc. https://processwire.com/api/ref/pages/find-raw/ Write to files using $files->putContents(); https://processwire.com/api/ref/wire-file-tools/file-put-contents/ Using a dedicated table breaks one of the features of PW vs WP - every field is a table! https://processwire.com/blog/posts/making-efficient-use-of-fields-in-processwire/ That being said, if you wanted to create a special field that compounded a bunch of related values together, you could look at this module: https://processwire.com/modules/fieldtype-events/ If you are looking for a tutorial that includes creating a custom class to store your value, a more advanced overview is here:
  4. Right, so if it is on the field will not instantiate. Turned off it works fine. The weird thing is that I have something that watches for new elements so that if you have items open that haven't loaded yet and add a new item, the other items will initialize.
  5. I have this working well, it's lined up to release in a little bit. I have run into issues dealing with repeaters because the lack of repeater JS events related to opening and AJAX loading. So there is some limited repeater support until I work out a solution. I will dig in a little deeper after the initial release. Any insight into this issue is welcomed.
  6. Has this problem ever been resolved? Is there an alternative strategy? I have run into this situation with my grapick module. I have a mutation observer watching ProcessPage Edit and initializing fields once nodes are added to the DOM, but it only works in the repeater items that are already open. It would be nice to have some sort of trigger. Alternatively, perhaps I could build a list of fields using my fieldtype, fieldgroups that contain that field, compare it with a list of fields used on a page template, and then I guess watch the repeater/repeater container for new nodes? Oh but that doesn't help because a repeater is a list in a list in a list right?
  7. If an Inputfield requires third party libraries, it makes sense to includes them in the renderReady() method in the Inputfield module file. So for example if you need to include special CSS and/or JS files.
  8. I feel like this is getting very close to a release. The 'Stops' area is the primary data section of the field. If you want to create your own gradient color/stop combos by entering them here you can. AARRGGBB^0-100 is the format with pipes in between. The spectrum color picker is used in the builder. I haven't figured out how to get showIf to work with fields in this context, but the rules will only apply values that make sense with regard to the type of gradient you wish to build. I did include repeating linear and ellipse. I realized at the end I completely overlooked conical, but I know it is getting more use in gradient border button application techniques so I will add it. The repeating method takes your stops, divides them by 100 and multiplies them by the number you put in for size. If you don't put in a number, it defaults to 100px. There are many ways to declare the size of repeating patterns, but this seemed to make the most out of the Grapick format. Everything updates in realtime as you make changes. Might be less intensive ways to do that - I'm looking into it. As a standalone it works, I need to review some of the notes people have made about context and do some testing in repeaters before I release it. I have set up the client-side stuff to accomodate multiple isntances of the builder on a pageedit form, but I'd like to do a little more testing to make sure everything saves properly. I also want to make sure the API works as expected - e.g. if you use the API to set the stops portion can you get the rule out and so on.
  9. I've been trying to get conditional appearance to work for an InputfieldFieldset that is loading as part of the Inputfield render. I'm trying to use name selectors and values from dropdowns but for some reason I can't get things to match. To be clear, this is the form rendered by the Inputfield module when the custom field is included in a page. Perhaps because they are technically subfields of the main field included in the page this can't be done?
  10. FieldtypeGrapick The FieldtypeGrapick module for ProcessWire wraps the Grapick vanilla javascript gradient creation UI and extends the feature set to include settings beyond what the original library allowed for. The original javascript library was written by Artur Arseniev. Aside from requiring ProcessWire 3, the requirements are: PHP >= 7.2 or >= PHP 8.0 This module makes use of the Spectrum colorpicker library. Repeater and RepeaterMatrix items are supported. There is a gremlin in RepeaterPageArray iteration that causes warnings. I've created an issue for it. It does not impact performance. CssGradient Object The FieldtypeGrapick field value is a CssGradient object. $gradient = new CssGradient( $options=[] ); where $options is a list of properties: $options = [ 'style' => 'linear', 'stops' => 'FFFFFFFF^0|FF000000^100', 'angle' => '180', 'origin' => '', 'size' => '', ]; Properties The CssGradient style by default is linear, 180deg, with a white opaque stop at 0% and a black opaque stop at 100%. style $gradient->style: gives you the dropdown value of the style of gradient. Setting this automatically uses the correct settings for the css function and shape parameter as required. Possible values: 'linear' = Linear 'radial-circle' = Radial Circle 'radial-ellipse' = Radial Ellipse 'repeating-linear' = Repeating Linear 'repeating-radial-circle' = Repeating Circle 'repeating-radial-ellipse' = Repeating Ellipse 'conical' = Conical 'repeating-conical' = Repeating Conical Any other value defaults to linear. Depending on the type of gradient selected, origin, angle, and/or size will come into play. The stops are always used to determine the order of colors and their relative locations according to the limitations of each style. origin $gradient->origin: gives you the dropdown value of the origin of the gradient as it applies to radial and conical gradients. The format is X%_Y% if for some reason you want to set a custom X/Y origin. The dropdown values are typically what I find useful for most applications, but I am open to adding other presets. '-100%_-100%' = Far Top Left '50%_-100%' = Far Top Center '200%_-100%' = Far Top Right '-50%_-50%' = Near Top Left '50%_-50%' = Near Top Center '150%_-50%' = Near Top Right 'top_left' = Top Left 'top_center' = Top Center 'top_right' = Top Right '-100%_50%' = Far Middle Left '-50%_50%' = Near Middle Left 'center_left' = Middle Left 'center_center' = Center 'center_right' = Middle Right '150%_50%' = Near Middle Right '200%_50%' = Far Middle Right 'bottom_left' = Bottom Left 'bottom_center' = Bottom Center 'bottom_right' = Bottom Right '-50%_150%' = Near Bottom Left '50%_150%' = Near Bottom Center '150%_150%' = Near Bottom Right '-100%_200%' = Far Bottom Left '50%_200%' = Far Bottom Center '200%_200%' = Far Bottom Right angle $gradient->angle: gives you the angle in degrees of the gradient as it applies to conical and linear gradients. Should be a value between -360 and 360. Measured in degrees. size $gradient->size: gives you the size - of what depends on the type of gradient. For radial ellipse gradients, at applies a size of XX% YY% using the value. So 25 would represent a size of 25% width, 25% height of the container. For repeating linear, conical and radial gradients, the repeating gradient will apply the percentage stops as a percentage of this value. In the case of repeating linear gradients, if you have your stops at 0%, 10%, 50% and 100% and your size is 200, the stops in the calculated rule will be at 0px, 20px, 100px and 200px. For repeating ellipse and conical gradients, a similar calculation is performed, but the units are %, not px. You can get some crazy tartan backgrounds out of this if you stack your gradients up and are creative with transparencies. stops $gradient->stops: gives you the current stop settings in a AARRGGBB^%% format, with each stop separated by a '|' character on a single line. You can role your own gradient ruleset by modiying this property prior to getting the rule. When using the UI you can also reveal the Stops inputfield and change the stops manually, however you will need to save to see the changes in the UI. rule $gradient->rule: gives you the stored rule that is calculated prior to the field value being saved to the database from the UI. Of course, if you are ignoring the UI altogether and just using the class, you will probably ALWAYS want to call getRule() rather than use this property. If you render the field, it will return the rule as a string. Methods The CssGradient has a single public method that is mostly useful when manipulating an instance of the CssGradient class. getRule(string $delimiter) $gradient->getRule(): calculates the rule based on the properties or options you have set for the field. This automatically runs if you have set an $options array and populate the rule property, but if you decide later that you need to change the properties of the object, you'll want to manually call it again to recalculate it. For example, if you programmatically change the stops, you will want to run the getRule() method rather than just grab the rule property. If you pass a string, the first character will be used as an ending delimiter. If you pass an empty string, no ending delimited will appear. By default, the rule is output with a semicolon. Grapick UI The Grapick UI is relatively straightforward. Clicking the (x) handle above a gradient stop removes the stop from the gradient calculation. If you remove all the stops, the bar is transparent. Clicking on the gradient bar sets a stop conveniently set to the color you click on. Clicking on the colorpicker box below the stop line allows you to select the color and transparency of the stop. Click and drag the stop line itself to modify the gradient. Making changes to any of the controls on the field will update the preview and the calculated rule in real-time. You can always cut and paste this rule and use it in your designs elsewhere if you want. Likewise, if you open the Stops inputfield area (which is collapsed by default) you can directly alter the colors and code using a color in an AARRGGBB format and adjust the stop with a number from 0-100. It's fun to play with - experiment with hard and soft lines, size and origin - many interesting effects are possible. Do not forget that the alpha slider is also available. Examples $grk = new CssGradient($options=[ 'style' => 'linear', 'origin' => '', 'angle' => 270, 'stops' => 'FF8345E4^0|FF5A08DB^25|FF2C046B^97|FF000000^100', 'size' => '', ]); echo $grk->getRule(); will give you: linear-gradient(270deg, rgba(131, 69, 228, 1) 0%, rgba(90, 8, 219, 1) 25%, rgba(44, 4, 107, 1) 97%, rgba(0, 0, 0, 1) 100%); while echo $grk->getRule(''); will give you linear-gradient(270deg, rgba(131, 69, 228, 1) 0%, rgba(90, 8, 219, 1) 25%, rgba(44, 4, 107, 1) 97%, rgba(0, 0, 0, 1) 100%) and echo $grk->gerRule(','); will give you linear-gradient(270deg, rgba(131, 69, 228, 1) 0%, rgba(90, 8, 219, 1) 25%, rgba(44, 4, 107, 1) 97%, rgba(0, 0, 0, 1) 100%),
  11. Yeah sure I can do PRs if you want. I ended up forking your migratePageClasses method and cutting out the migration aspect and calling it detectPageClasses. I understand why its pretty redundant for your purposes (primarily page classes in custom modules) but being able to run something to quickly check in directories for new classes without doing a full migration is helpful for my use case.
  12. An issue exists for some users when trying to adjust the thumbnail size slider on image fields if you have the 'hold on fields header to lock' toggle enabled. There also seems to be a delay setting that is undocumented. Is that 700ms for the long hold to lock? Perhaps increases the duration of the long click would help.
  13. I read A LOT of your source code because I have to diff with changes I've made to accommodate my requirements. So the template creation should happen first. Got it. Maybe. The mechanics are usually clear but it sometimes isn't obvious what is triggering what, and in what order. And I know you like "triggering" things 🤣 // object to migrate // usage: $rm->watch("file.php", true, ['trigger'=>$something]); // will trigger $something->migrate() when file.php changes // see RockCommerce.module.php/Product for an example 'trigger' => false, I like the idea of this. Should be fun to build with.
  14. Okay, I found my template to templates typo in the config array. I also forgot that at one point I added in a migratePageClasses method call but subsequently removed it. Putting it back in triggered the migrations in those class files. It seems like once the template name is in the 'magic-templates' cache they are watched/migrated. If I am not putting my classes in a separate module, would I still use migratePageClass? It seems like the preferred pageClassLoader is only for migrating classes that are in a modules file set.
  15. Hey I just saw the new release of 3.34 - and it looks like perhaps there is a cache getting cleared now. I will give it a try and let you know how it goes.
  16. Using RockMigrations 3.33.0 when I copy new custom page class files to the classes directory they aren't getting added to the watchfile list automatically. Previous versions picked up magicpages and added them. Even after I try to add them using watch() and watchPageClasses() for some reason when I output the watchlist they are not appearing. Page classes that already exist are watched - when they are updated the migrations run fine. Is there a watchlist cache I need to clear someplace? None of these classes are part of a module, they are all simply in the classes directory off the root pw folder. e.g. /pw/site/classes/ My page class structure hasn't changed. It's pretty simple. <?php namespace ProcessWire; use RockMigrations\MagicPage; class TestingPage extends Page { use MagicPage; const tpl = 'testing'; const group = 11.55; // I added a check for this constant in the watch() method for instanceof Page so I can have more control over migration order. public function migrate() { $rm = $this->wire->modules->get('RockMigrations'); $rm->migrate([ 'template' => [ 'testing' => [ 'fields' => [ 'title' => [ ], ], 'fieldgroups_id' => 'testing', 'flags' => 0, 'cache_time' => 0, 'sortfield' => 'name', 'useRoles' => 1, 'noParents' => 1, 'childTemplates' => [ 0 => 'test-child', ], 'parentTemplates' => [ ], 'slashUrls' => 1, 'noMove' => 1, 'childNameFormat' => 'title', 'noChangeTemplate' => 1, 'noShortcut' => 0, 'compile' => 3, 'label' => 'Testing', ], ], 'roles' => [ 'guest' => [ 'access' => [ 'testing' => [ 'view', ] ], ], 'copy_editor' => [ 'access' => [ 'testing' => [ 'view', ], ], ], ], 'pages' => [ 'testing' => [ "template" => "testing", "title" => "Testing", "parent" => "name=options,template=options-main", "status" => [ 'on', ], ], ], ]); } } ?> In my install the Options page does already exist.
  17. Yeah I did find it that way as well. Thanks! I also forgot until I did a code audit yesterday that it is pretty trivial to override the getPageListLabel() method when using page classes. It still might be worth bringing the parsing over for folks not interested in doing it that way.
  18. How did you get to that API ref page? I could only find this one, which is empty. https://processwire.com/api/ref/pages/names/
  19. Yes it is, I created an issue for the feature: https://github.com/processwire/processwire-requests/issues/514 Essentially I would like to be able to use something like {created:yy-mm} to be able to show alternative forms of the datetime in the label. Should be an easy fix since the parsing code already exists in the PagesNames class (in theory).
  20. Not sure I fully understand your question, but the search results page is simply a page with a template that sanitizes your search form and runs a find on it (or if you use the SearchEngine module you have additional options). Take a look at templates/search.php and you will see a basic model. <?php namespace ProcessWire; // look for a GET variable named 'q' and sanitize it $q = input()->get('q'); // sanitize to text, which removes markup, newlines, too long, etc. $q = sanitizer()->text($q); // did $q have anything in it after sanitizing to text? if($q) { // Make the search query appear in the top-right search box. // Always entity encode any user input that also gets output echo '<input id="search-query" value="' . sanitizer()->entities($q) . '">'; // Sanitize for placement within a selector string. This is important for any // values that you plan to bundle in a selector string like we are doing here. // It quotes them when necessary, and removes characters that might cause issues. $q = sanitizer()->selectorValue($q); // Search the title and body fields for our query text. // Limit the results to 50 pages. The has_parent!=2 excludes irrelevant admin // pages from the search, for when an admin user performs a search. $selector = "title|body~=$q, limit=50, has_parent!=2"; // Find pages that match the selector $matches = pages()->find($selector); } else { $matches = array(); } In the end you have a $matches array returned by the find() method. But you could create different search pages to represent different form actions and filter the results to be what you wish on the respective processing template. So for example you might modify your $selector to only include descendents of a certain branch, or certain templates unique to a single site, etc. If you are not familiar with the power of selectors, this is a key place where you will want to dig deep: https://processwire.com/docs/selectors/ Does that make sense? There isn't anything really special about the search page aside from the sanitizing and find() functions found in the template file. By setting your own search form action pages (multiples if you wish) with different page templates you can create topical search engines or whatnot. I guess my point is that you aren't limited to just one search template, or one search action URL. If it was me, I'd probably create separate search templates for each site, dedicate a page under each site tree for each, and point the forms on the respective sites to the respective search pages. Both forms will process find against the same page tree, but you can filter the find selector in advance, adding whatever query post gets sent from the form.
  21. I thought I recalled somewhere seeing that it was possible to format the timstamps for the pageListLabel. Did I dream it? Is that just a fantasy? Something like {created:YYYY-mm} or something like that? Can the createdStr date format be configured in a setting someplace? I can do this with other means but for some reason I felt like there was a way to do this... Maybe I'm confusing it with being able to alter the date in the default child naming setting?
  22. Hello, Not sure if this is a simple request - it just came up in use, but can we choose in the config whether the 'Add New' menu item appears at the top or bottom of the dropdown? That field list can get kindof lengthy. It would be nice to have it available at the top if I wish.
  23. Love what I am seeing here. Having the ability to clone an old version into a new page might also be handy.
  24. I can mitigate it via the API/migrate() so I guess it isn't an issue. I did find that RockMigrations doesn't take existing page titles into account when updating data so I will make an issue in RM for that.
×
×
  • Create New...