Jump to content

MarkE

Members
  • Posts

    931
  • Joined

  • Last visited

  • Days Won

    10

Posts posted by MarkE

  1. 3 hours ago, bernhard said:

    If you have a look at the RockFrontend Site Profile you'll see that it should work without namespaces:

    It works for me too in a similar context - i.e. when calling it to output: i.e in {$page->foo()} - but not when called in a variable declaration - ie. {var $foo = $page->foo()} That's when I seem to need {var $foo = $page->ProcessWire\foo()}. Odd.

    EDIT - Correction: The issue occurs not with page classes but just with functions defined in init.php (which is in the ProcessWire namespace.

  2. I do love Latte, but one little thing is puzzling me at the moment: namespaces. I am using custom page classes for all my 'business logic' - e.g a method getEmailHash() in the custom page class called in the Latte script with $page->getEmailHash(). The class has the namespace ProcessWire. It seems that I always need to specify the namespace in the method  - i.e. $page->ProcessWire\getEmailHash().

    Is there a way of avoiding this?

  3. I've only just spotted this but, in my ddev environment, if I modified a page the modified date was always recorded as one hour earlier.

    So 

    Quote

    Last modified by admin on 2024-04-18 13:55:19 (1 hour ago)

    appears on the settings tab immediately after doing a modification (at 14:55).

    The production environment was OK. I have $config->timezone = 'Europe/London'; throughout in config.php. It seems that you also need to set the timezone (in my case 'timezone: Europe/London') in the ddev config.yaml

    • Like 2
  4. On 4/11/2024 at 2:37 AM, Robin S said:

    I've removed the InputfieldPage::isValidPage() check in v0.3.7 because it seems unnecessary

    Thanks @Robin S - I think that's an improvement (although I'm not sure if it may be slightly less efficient). However, it doesn't really solve my problem: I realise after sleeping on it that my code is actually setting both sides of the pair anyway and so may be conflicting with ConnectPageFields. I changed my code to save the page with 'noHooks' => true and it all works fine. It also fixes the earlier problem, so I'll update your issue for that as it was proving difficult to tie down the source of the null page. 'noHooks' may have side effects, however, and I'm wondering if I can just temporarily turn off ConnectPageFields.

    EDIT: not updated issue as the issue description perfectly explains the problem outside my context

  5. Hi @Robin S. I'm still investigating this. However, in the course of my investigations, I discovered another problem I was having with the ConnectPageFields::updateConnectedFields($page, $field) method. What I understand happens is that the entire array of connected fields which pair with the field on the page is run through and an update occurs if the page passes the 'isValidPage' test for the other field.

    Unfortunately, 'isValidPage' also sets an _isValidPage attribute (error message) which then seems to 'stick' on the page. In my particular usage, this seemed to prevent the valid 'other field' (which occurred later in the connected fields array) from updating.

    I'm probably being a bit thick (it is a bit late here) but I don't see why fields are attempted to be updated when they don't exist on the page. I added 

    if(!$page->hasField($other_fname)) continue;

    after line 

    $other_fname = $other_field->name;

    and everything seemed to update fine.

    I can provide more background to the situation if required.

    EDIT: Actually that last bit is not the right solution, but I need to sleep on it!

  6. Hi @adrian. I just tried to use this module for the first time and hit a snag. If a config field references a page, then the module uses the page id as the value. Fair enough, but it does not work if the target environment has different page ids (which may be the case if your development database is not an exact clone of the production database - in which case you probably don't need this module anyway).

    In my ProcessDbMigrate module, I get round this by converting ids to paths (and providing a mapping if the paths have changed - which is far less likely). I was going to add a module migration component to ProcessDbMigrate, but then came across this module which I thought would do the trick. Is it possible to modify ModuleSettingsImportExport, or am I best to go ahead with my original plan and extend ProcessDbMigrate, in which case, can I 'borrow' a bit of code from your module (with accreditation)?

  7. Interesting topic and also interesting to compare the various CMSs at https://openalternative.co/categories/cms. Unfortunately it is not possible at-a-glance to see what is a pure CMS and what is more of a framework. The initial attraction of ProcessWire to me was that it combines the ease of use / UI of a CMS with the power and flexibility of a framework. This means that you can build a fully functional custom app but still enable non-technical editors to access the content they need. 
    Which of the “ProcessWire-like” CMSs do that?

    • Like 1
  8. 1 hour ago, Robin S said:

    If your code is somehow producing a Page object that lacks an ID then I think that's a core issue

    I'll investigate. I suspect it may be connected with an export method that never seemed to have been completely finished although part of the core.

  9. Thanks @Robin S. I also got this error (after the fix), which might be related:

    325420606_Screenshot2024-04-06113914.thumb.png.f907979ea9eaebd9e75d07db56858756.png

    As you can see, it seems to be caused by a null item being included in an implode. I'm seeing if I can fix that too.

    Update:

    Added this after line 125, which seems to fix it:

    			// Remove any null pages and continue if the new value is empty
    			if(!$new_value) continue;
    			if($new_value instanceof PageArray) {
    				foreach ($new_value as $valueItem) {
    					if ($valueItem instanceof NullPage) {
    						$new_value->remove($valueItem);
    					}
    				}
    				if($new_value->count() == 0) continue;
    				if($new_value->count() == 1) {
    					$new_value = $new_value->first();
    					$this_is_multi = false;
    				}
    			} else {
    				if($new_value instanceof NullPage) continue;
    			}

    I'm not sure how the null pages were getting in there - probably something specific to my set-up - but hopefully the above code doesn't have any side-effects.

  10. Sorry to say @bernhard, that I seem to have run out of road on this one. I compared two identical windows, one showing it correctly and the other not. The css was identical and there were no media queries.

    I compared the html and there are very minor differences in some of the width settings, which you can see being changed by js as the window is dragged between screens. The main one was this div:

    <div role="application" class="tox tox-tinymce tox-tinymce-inline tox-tinymce--toolbar-sticky-off" aria-disabled="false" style="visibility: hidden; display: flex; position: absolute; left: 10px; top: 826px; width: 591px;">

    which is the html on the 'correct' rendering and this:

    <div role="application" class="tox tox-tinymce tox-tinymce-inline tox-tinymce--toolbar-sticky-off" aria-disabled="false" style="visibility: hidden; display: flex; position: absolute; left: 11px; top: 830px; width: 591px;">

    which is the rendering with the drop-down above the icon line (which is what causes the problem). All the other width changes appeared to be fractions of a decimal and there were no other html differences. I manually changed the 'bad' html to be the same as the'good' html using developer tools, but there was no noticeable effect.

    So I am pretty much stumped. Maybe @ryan, who must have a deeper understanding of what the js is doing (much of it is minimised) could shed some light?

  11. Hi @bernhard. It's really weird. If I move a window from one screen to another, the problem fixes itself. Move it back to the original screen and it reappears. What is happening is that the 'bold' dropdown you can see in the image I posted appears between the menu and icon lines, causing the bottom of the toolbar to drop down. When I move the window to a different screen the 'bold' dropdown is displayed inline with the icons. This is with no interaction other than simply dragging the window, so it looks like maybe a css issue? Still looking....

  12. 32 minutes ago, MarkE said:

    Meanwhile the custom row is another option which is less user-friendly, but probably better than just allowing a selector input ion a plain text field.

    However, I also had problems using the generated result (e.g. 'template=96, _custom="eventDate>2 months ago"') in the $pages->find() api. It returned all pages matching the template. I had to use regex to turn 'template=96, _custom="eventDate>2 months ago"' into 'template=96,  eventDate>2 months ago' which seems a bit clunky.  The answer is to  set the allowCustom option to true in find().

  13. 9 hours ago, Robin S said:

    Here's how you might do it with some custom admin JS:

    That works @Robin S. Thanks a lot. However, as you say 

    9 hours ago, Robin S said:

    it seems that InputfieldDatetime will convert a time string to the equivalent timestamp

    so it doesn't meet my need for the relative date to be used dynamically, which is why I was wondering if what is really needed is an extension or modification of InputfieldDatetime so that it can store a strtotime-comprehensible text field. Meanwhile the custom row is another option which is less user-friendly, but probably better than just allowing a selector input ion a plain text field.

    • Like 1
  14. I've done some searching for an answer on this as I can't believe it has not come up before:

    My problem is that I would like to use a "selector" field (i.e. the interactive selector builder) to compare, for example, a datetime field with 'today'. The issue is that I want it to operate dynamically, so the comparator needs to be stored as 'today' and only converted when the selector is run.

    This works fine if I just use a text field instead of the selector field and allow the user to input a selector string - e.g. "myDatetime>today", but in the selector builder the comparison field requires an absolute date - a string entry of a relative date is impossible. However, for many reasons, I would prefer not to have a user attempting to enter a selector string.

    Has anyone tried something similar? If not, I'm toying with the idea of writing a module to extend InputfieldDatetime. That would permit the storing of a valid string as well as an actual date. The string would be only converted to a date at runtime. This would allow entering a date as, for example, 'last month' such that when the field is formatted it would be displayed as a date one month before the execution date. This contrasts with the present module where, although you can default to 'today', I think that is converted to a timestamp at the time of entry and stored as such. Any thoughts on that?

  15. @titanium I don’t know what the Cargo pagebuilder is like, but the website isn’t great. Did you look at PAGEGRID? I think it offers more flexibility than RockPageBuilder, which is good or bad depending on your point of view. I decided to make my own page builder which offers three levels of access: editor, designer, and developer. It’s still experimental at this stage, even though I started it before the two aforementioned page builders were released, but I might release a proof of concept version later this year. There are some difficult decisions to be made between ease of use / consistency and flexibility. For instance, I have (provisionally) decided that someone with designer access needs a certain level of css skills: enabling lots of GUI options for styles is complex to code and to use as well as inevitably not covering everything. 

    • Like 1
  16. 8 hours ago, kongondo said:

    One big screen might be better than two smaller ones (central focal point) - YMMV!

    I use three. Central one 24”, sides 17”. I find that much better than one big one. Typically, the central one for code, one side for displaying the output and the other side for reference. Probably cheaper than one big one as well. 

    • Like 2
  17. Thanks for the comments @monollonom and @iank. Very helpful!

    22 hours ago, monollonom said:

    I usually set a CSS variable and add them with the style attribute where needed.

    I have used that approach, but forgot to mention it. It works well but, from a Tailwind point of view, it's pretty much like an inline style (except as noted below and probably with a bit of added overhead). In a typical case, I am setting an image width based on user input, so I can do (in Latte):

        <style>
            :root {
              --cardwidth: {$width};
              --cardheight: {$width};
              --imgheight: {$imgHeight};
        </style>

    The tag is then:

    <div class="[width:var(--cardwidth)] [height:var(--cardheight)]  ... etc...

    Although this is a bit messy, it does at least have the advantage of being clear what is being set, as opposed to some arbitrary class name. To quote the Tailwind docs 

    Quote

    This is really like inline styles, but again with the benefit that you can use modifiers

    -----------------------------------

    21 hours ago, iank said:

    The TailwindCSS JIT compiler scans the source code rather than the html output, so it's looking for full class names in your PHP code.  Hence you could do something like this:

    I can't get this to work, at least not with the variable width example quoted above. It will correctly generate (say) h-[200px] as the class in the HTML but it is not in Tailwind's output css.

    Similarly, class="[width:{$width}] ..... doesn't work - it seems it needs to be set as a css var first, although quite why that is, I'm not sure (See EDIT).

    21 hours ago, iank said:

    Or you could simply fake safelisting the expected values

    That's neat! I wasn't aware of that. It works well if there is only going to be a limited set of options which, unfortunately, is not the case for the width/height example.

    On balance, if I stick with Tailwind, it looks like css vars may be the way to go, but I'll do a bit more hacking about and, if I have any better ideas, will post them here.

    ----------------------------

    PS - see the result here. The site editor can change the card size. It also gives the opprortunity of easily adding responsive variants.

    ----

    EDIT: The reason why using a css custom property as an 'intermediary' for the variable works is that Tailwind can compile that (as var(--whatever)) to its output css, which happens before the php is interpreted to creat the css value which the html can then use.

  18. What approach do folks use when you want to dynamically set CSS? In particular, is there a preferred method when using Tailwind?

    As far as I can see, the approaches are:

    1. Use in-line styles either in the host tag or in an in-line style tag. This is simple and straightforward to do but seems to be frowned upon by purists and is arguably a bit messy-looking.
    2. Use LESS (or similar). But this does not play well with Tailwind.
    3. Dynamically create a css file including css variables. But LESS is better at this.
    4. Create a php style file.

    Are there performance issues with the last 2 approaches (or might they be overcome with caching).

    The problem with Tailwind is that, while you can refer to php variables in your Tailwind class, because the tailwind output is compiled before the php is run, if the php variable value is not already represented by a value in the tailwind output css (perhaps because it has been generated somewhere else by a non-variable input) it will be ignored. This issue is making me think about ditching Tailwind and switching to LESS, but perhaps that is an overreaction.

×
×
  • Create New...