Jump to content
adrian

Tracy Debugger

Recommended Posts

Hi @adrian

today Tracy cost me 1 hour of work 😞 

$this->addHookAfter('Session::loginSuccess', function(HookEvent $event) {
  bd('Session::loginSuccess');
});

No matter what hook I tried (Session::login, ProcessLogin::loginSuccess etc) tracy did not dump anything. It seemed that the hook did never fire. I even placed a bd('Session.php') in Session.php... nothing! 😮

I tried different Session Handlers (DB, default), tried hooking ::logout (which worked) etc etc.

Then I found:

$this->addHookAfter('Session::loginSuccess', function(HookEvent $event) {
  bd('Session::loginSuccess');
  $this->message('Session::loginSuccess');
});

H6XN4mh.png

So the hook fires, but the BD() call get's lost somewhere! The dumps recorder is also empty (not shown in the screenshot)!

Any ideas what could be going on?

 

PS: My new balance

  • Tracy time costs: 1h
  • Tracy time savings: 500h+ (thx once more!! 🙂 )
  • Like 1

Share this post


Link to post
Share on other sites

Hey @bernhard - I just tested here with all combinations of the following on my local dev setup (MacOS)

1) SessionHandlerDB on and off
2) Your hook in init.php and ready.php and in the Console panel injected at init and ready

In all cases, the bd() shows up in one of the Tracy redirect bars.

Then I tried on one of my linux servers and in all tests, the bd() call was never activated. My thought is that it must be something to do with when Tracy is loaded. Because Tracy is loaded by PW's module system, it isn't loaded until site modules get loaded. Ryan made it so that it is the first of these site modules to be loaded which means we can always reliably use it to test development of other modules, but it doesn't load before the PW core which is why it's sometimes impossible to use it to debug the core. 

All that said, I don't know if load order is the problem in this case, or if it's something else. I'd actually love to know if you see a difference on different servers / PW installs. And anyone else who'd like to test also - it would be good to figure out if there is something consistent with when it does and doesn't work.

  • Like 1

Share this post


Link to post
Share on other sites

Thx @adrian

the strange thing is. If the load order of the modules was the problem, shouldn't the bd() throw an error that the function does not exist? The hook seems to be fired, because the $this->message() shows up. 🤔

  • Like 1

Share this post


Link to post
Share on other sites
57 minutes ago, bernhard said:

the strange thing is. If the load order of the modules was the problem, shouldn't the bd() throw an error that the function does not exist? The hook seems to be fired, because the $this->message() shows up. 🤔

Yeah, that makes sense 🙂

Ok, so after spending way too much time, it's not specifically a Tracy issue. If you do a Tracy log call, eg:

$this->addHookAfter('Session::loginSuccess', function(HookEvent $event) {
    l('Session::loginSuccess');
});

then it works fine. The issue is that dumps are stored in a variable and added to as needed during the current request. But it seems like PW hasn't actually started its session at Session::loginSuccess. If you try the same bd() call at Session::init then it works as expected.

$this->addHookAfter('Session::init', function(HookEvent $event) {
    bd('Session::init'); // works
});

So, I looked into the possibility of making it possible to do bd() calls and have them carry over to the next PW session (after the login has actually started the session) and there are possibilities, but I think they all come with downsides. I think it might help the Dumps Recorder panel though in that I'll be able to make it keep data over sessions, so I might consider that. I'll mull it over for a bit.

As a reminder (almost just for myself), Session::loginSuccess does work on some setups (eg my local dev environment), so there must be some differences in how sessions are handled that is impacting this.

  • Thanks 1

Share this post


Link to post
Share on other sites

Just a quick update to you all know that there is a new keyboard shortcut for reloading a snippet from disk, clearing previous output, and running the code which should be a nice time saver and also prevent you from accidentally running old code in the console that hasn't been updated from the disk version when you are using an external editor.

image.png.6d6d7b0e97ad966ef651f65f2d096ef9.png

I have also rejigged the execution of code when "Run" is called vs injecting. Hopefully the visual cues of the button changing from "Run" to "Inject" and the status in the header showing "Inject @ Ready" makes it more obvious what is going to happen when.

Another update is that the Dumps Recorder panel now stores its data in a file so that it will survive across sessions which may be useful if you are hooking certain session methods and other scenarios where the normal Dumps panel is not showing your bd() calls.

  • Like 5

Share this post


Link to post
Share on other sites

New toggle arrow to collapse / show the snippets side pane with the state remembered via cookie.

image.thumb.png.42b1fdba3b216cbca94919b935553c1c.png

VS

image.thumb.png.458796aa658f7f957069808dfc7cb72d.png

  • Like 2

Share this post


Link to post
Share on other sites

If you work with deeply nested / large JSON data and you use Adminer, the latest update will allow you to speed things up significantly with a few new config options. I've also included a PR to the JSON preview plugin which this functionality relies on - my changes ensure the max text length setting is applied to json that is kept as a string due to the max level setting. 

image.thumb.png.21dd7e8af779db08b729e882c6bb5f5e.png

  • Like 3

Share this post


Link to post
Share on other sites

Hey @adrian unfortunately I have some very strange issues with the dumps feature 😞 

This is the code I have (using Nette Forms):

[...]

    l('renderMail');
    bd('renderMail');

    // submit
    if($form->isSuccess()) {
      l('success!');
      bd('success!');
      $session->redirect('thank-you-page');

[...]

I have several problems:

1) The bd() calls do only show up in the dumps recorder, not in the regular AJAX bar dump.

2) The dumps recorder shows the entries twice whereas the tracy logs show them only once.

ZawHTd4.png

The tracy logs should be the correct results, because after the form success I do a session redirect to the thank you page. No idea why things show up twice in the dumps recorder. Of course I have cleared the dumps before submitting the form 😉 And it's the latest version of tracy from today (4.21.10)

Explanation of the dumps recorder:

1) renderMail is called on the initial page view (correct, logs at 18:10:12)

2) renderMail is called when the form was submitted (correct, logs at 18:10:21)

3) success is fired because the form was successfully submitted (correct)

4) send mail is fired correctly

5) 2, 3 and 4 are dumped again (not correct)

 

Here another dump showing timestamps:

CSaF8jm.png

 

Any ideas? 😞 

Edit:

I checked by sending an email additionally to the "send mail" dump:

  public function send($message, $contact) {
    bd("send $message to $contact");
    $mail = new WireMail();
    $mail->to('foo@bar.com');
    $mail->from('foo@bar.com');
    $mail->subject("Test @ ".date('d.m.Y H:i:s'));
    $mail->send();
  }

The mail was actually sent twice, so it seems that the tracy dump is correct. So what about the tracy log? Shouldn't that also be listed twice then? No idea why that send() call fires twice at all... there is a session redirect that should prevent this 😞 

Share this post


Link to post
Share on other sites
3 minutes ago, bernhard said:

1) The bd() calls do only show up in the dumps recorder, not in the regular AJAX bar dump.

Is a new AJAX bar showing at all (even without a Dumps panel entry). If it's not, then it's probably an issue with Nette forms not sending the 'X-Requested-With': 'XMLHttpRequest'

8 minutes ago, bernhard said:

after the form success I do a session redirect to the thank you page

Or maybe it's related to that - if it's an AJAX form submission and then you do a redirect afterwards, that a) seems to defeat the reason for an ajax submission, and b) is probably why the AJAX bar is lost. Does it show in the ajax bar if you don't do the redirect?

11 minutes ago, bernhard said:

2) The dumps recorder shows the entries twice whereas the tracy logs show them only once.

Not sure about that - I'll look a little later and after I hear back about those possible reasons for #1

Share this post


Link to post
Share on other sites
2 hours ago, adrian said:

Is a new AJAX bar showing at all (even without a Dumps panel entry). If it's not, then it's probably an issue with Nette forms not sending the 'X-Requested-With': 'XMLHttpRequest'

There's only one single bar. But it's not an AJAX request. I'm submitting the form as regular POST and then doing a session->redirect to a new page. But usually tracy also log's redirected requests (like after page save).

Sorry about the ajax confusion! I meant those redirect bars:

bIxCZSn.png

Share this post


Link to post
Share on other sites
On 5/4/2020 at 6:24 PM, bernhard said:

The mail was actually sent twice, so it seems that the tracy dump is correct. So what about the tracy log? Shouldn't that also be listed twice then? No idea why that send() call fires twice at all... there is a session redirect that should prevent this 😞 

I found the reason for this: I'm rendering a repeater with several blocks. There are two subscription blocks with nette forms. A form submit triggers the redirect but the redirect does not happen immediately because it does finish() the active process, hence renders the other blocks as well. That's why I got 2 dumps (one for each block). I added a custom instandRedirect method to my repeater blocks:

public function instantRedirect($url) {
  header("Location: $url");
  exit(0);
}

 

Share this post


Link to post
Share on other sites

Hi @adrian, I'm getting the following error in the RequestInfo panel with  many of my custom modules, do you know what's causing this?

ProcessWire\WireException: Method TrelloWire::getArray does not exist or is not callable in this context in /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/wire/core/Wire.php:529
Stack trace:
#0 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/wire/core/Wire.php(386): ProcessWire\Wire->___callUnknown()
#1 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/wire/core/WireHooks.php(823): ProcessWire\Wire->_callMethod()
#2 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/wire/core/Wire.php(450): ProcessWire\WireHooks->runHooks()
#3 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/wire/core/Wire.php(453): ProcessWire\Wire->__call()
#4 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/site/assets/cache/FileCompiler/site/modules/TracyDebugger/panels/RequestInfoPanel.php(295): ProcessWire\Wire->__call()
#5 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.7.x/src/Tracy/Bar/Bar.php(150): RequestInfoPanel->getPanel()
#6 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.7.x/src/Tracy/Bar/Bar.php(122): Tracy\Bar->renderPanels()
#7 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.7.x/src/Tracy/Bar/Bar.php(98): Tracy\Bar->renderHtml()
#8 /var/www/vhosts/klforexpats.preview-server.dev/httpdocs/public/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.7.x/src/Tracy/Debugger/Debugger.php(293): Tracy\Bar->render()
#9 [internal function]: Tracy\Debugger::shutdownHandler()
#10 {main}

This happens in the module configuration (in this case the module is TrelloWire, but I get this with most custom modules). Is this indicative of some problem with my module? Or just some strange interaction between the module config and Tracy?

Share this post


Link to post
Share on other sites

@MoritzLost - from my initial investigation, it looks like a PW core bug. You are using this (https://processwire.com/blog/posts/new-module-configuration-options/#enter-the-new-moduleconfig-class) approach to defining module settings which I have never used, but it appears that when that approach is used, the getArray() method doesn't exist on the module, hence the error.

Do you know of another module that uses that approach that I could test to confirm?

 

  • Like 1

Share this post


Link to post
Share on other sites

@adrian I have tested my other modules; I think the error only occurs when the module does NOT extend WireData, since the getArray method comes from there.

  • TextformatterPageTitleLinks extends Textformatter which extends WireData -> RequestInfoPanel is working.
  • ProcessCacheControl extends Process which extends WireData -> RequestInfoPanel is working.
  • TrelloWire extends Wire (instead of WireData) -> RequestInfoPanel displays the error.
    • When I change the class definition to extend WireData instead of Wire, the error disappears.

I have tested & confirmed this behaviour with another module I'm working on (currently not publicly available, will probably publish this next week or so). So I think it comes down to modules that don't extend WireData at all, which isn't required (at least according to the docs). I guess it's mostly a cosmetic choice, but for the modules that don't really keep track of data I didn't want to extend WireData. Maybe the RequestInfoPage could check for that case and use getModuleConfig instead?

  • Like 1

Share this post


Link to post
Share on other sites

Hi @adrian,

I've been cleanin' up my latest project and noticed this warning:

Cookie “tracyClearDumpsRecorderItems” will be soon rejected because it has the “sameSite” attribute set to “none” or an invalid value, without the “secure” attribute. To know more about the “sameSite“ attribute, read https://developer.mozilla.org/docs/Web/HTTP/Cookies

I don't know if it means anything. If so, great. If not, please ignore this post. 🙂

  • Like 1

Share this post


Link to post
Share on other sites

Thanks @MoritzLost for figuring that out. I have added a check to prevent that error when a module doesn't extend WireData. Honestly, I think the getting of module settings in PW is a bit of a mess which is why I use 3 different approaches in Tracy because they all return different things for some modules. Let me know if you have any problems with the new version.

Thanks @rick for the heads up on that. I took a quick look, but I don't have time to fix things at the moment - I set a lot of cookies in various places in Tracy and I am not using a standard method so it's not easy to change them all and I sometimes set in JS and sometimes in PHP. Obviously I don't want to make them "secure" because I am sure many of us are running local dev setups without https, so I probably need to just set the sameSite rule to Lax, but maybe Strict is better? Not sure yet, but it's on my list to take care of soon.

  • Like 1

Share this post


Link to post
Share on other sites
32 minutes ago, adrian said:

Thanks @MoritzLost for figuring that out. I have added a check to prevent that error when a module doesn't extend WireData. Honestly, I think the getting of module settings in PW is a bit of a mess which is why I use 3 different approaches in Tracy because they all return different things for some modules. Let me know if you have any problems with the new version.

Thanks for the fix @adrian, I just tested it and it seems to be working! I'm not getting errors any more with both modules I tested before 🙂 

34 minutes ago, adrian said:

Thanks @rick for the heads up on that. I took a quick look, but I don't have time to fix things at the moment - I set a lot of cookies in various places in Tracy and I am not using a standard method so it's not easy to change them all and I sometimes set in JS and sometimes in PHP. Obviously I don't want to make them "secure" because I am sure many of us are running local dev setups without https, so I probably need to just set the sameSite rule to Lax, but maybe Strict is better? Not sure yet, but it's on my list to take care of soon.

Just butting in here: I don't believe you want to use Strict, this may break the debugger for if you visit the site by clicking on a link from somewhere else. Since you can't really use Secure cookies because of the local dev environments like you said, you'll probably be best of with SameSite=Lax to most cookies. This article on web.dev is a good resource for the SameSite changes.

  • Like 1

Share this post


Link to post
Share on other sites
1 minute ago, MoritzLost said:

Just butting in here: I don't believe you want to use Strict, this may break the debugger for if you visit the site by clicking on a link from somewhere else. Since you can't really use Secure cookies because of the local dev environments like you said, you'll probably be best of with SameSite=Lax to most cookies. This article on web.dev is a good resource for the SameSite changes.

Much appreciated - I'll admit to not knowing too much about these options yet, so great to get some more knowledgeable input. Thanks!

  • Like 1

Share this post


Link to post
Share on other sites

Hey @adrian,

would it somehow be possible to get the tracy console in a separate process module? I'm working on my RockFinder and there I have built a "RockFinderTester" process module that does basically the same thing like the tracy console, only a lot worse 😄 I have many modules where a console feature would be great for testing. At the moment I'm using the console for lots of things, but I wonder how complicated it would be to move the console to a separate page that we can modify to our needs.

So for example for testing a RockFinder it might be great to have the code input on the top and below that it would be great to have an area where I can not only dump variables but also show the result as paginated table (using tabulator.js). The tabulator part could totally be done by me - I'd only need to have the proper JS events I can listen for.

I know we have the console snippets at the moment, but I think the console is such a powerful tool, that it would be great if it could be used by other modules as well.

Do you understand my idea? Would that be very complicated to achieve? Thanks in advance for thinking about it 🙂 

Share this post


Link to post
Share on other sites
16 minutes ago, bernhard said:

I wonder how complicated it would be to move the console to a separate page that we can modify to our needs

I have thought about making it a separate Process module so it can be opened on it's own page in the PW admin, but I am not sure about making it modifiable - what would you need to modify for you needs? Based on your tabulator example, it sounds like you are talking about extending the output options? But how best to do that? Is it just a matter of being able to inject (in the background) some additional JS to process the code and format as a table?

I am happy to talk about this more, but I haven't enough time at the moment to do anything substantial on this unfortunately. If you could think through how it should work in some more detail, that might make make it easier for me to implement. Of course PRs are also welcome, but I am happy to help implement if you figure out a plan for how it should work.

 

Share this post


Link to post
Share on other sites

Thx adrian,

this is what I have currently in my RockFinder2 module:

lTFDooA.png

This is basically a sandbox where one can test finders, sees a dump and also sees the data listed as tabulator. When looking at the code of RockFinder2 today I was quite surprised that it has +1200 lines of code. I had in my mind that it is quite lightweight compared to RockFinder1 because it builds upon the pw core query classes. Then I realized that I actually have lots of stuff packed into RockFinder2 that imho does not belong there. The finder tester is one of those things! I want to remove that part from the module so that RockFinder3 will just do one thing: Finding PW data and returning it as array of objects.

Nevertheless the finder tester is useful! So I don't really want to drop it as a whole. I can use the tracy console and do this:

kuqEJZp.png

This is already great, but it would be even greater if I could see the data in a tabulator. That's what I have in my process module, BUT: What I do not have there is the dumping features of the tracy console. Look at the first screenshot: There is a dump, but I always dump the returned finder object. I cant to any other dumps, because it's a custom implementation of the console. I also don't have the same settings and shortcuts as in the console.

Vision: Ideally I'd like to build RockFinder3 with only the features that it needs and pack the tester in a separate module. This module would require tracy (but only the process module, not the finder module) and could use the tracy console process. This process would show an InputfieldForm that everybody could modify easily via hooks. So I could just add a new InputfieldMarkup to that form below the tracy console, add some lines of javascript that intercept the AJAX events sent by the console and then show the result as tabulator grid.

Hm. I see that the ajax response at the moment does only send the html of the dumps. Maybe it could instead send the response as JSON? One property being the dump: "<foo>bar</foo>" and the other property being the returned value:

3Uob1Z6.png

In this case the code would return a RockFinder2 instance, so we would need something on the backend that transforms the returned data (here the rockfinder) in something readable by the client. Maybe something like this:

// pseudo code
$wire->addHookAfter("Console::getPayload", function($event) {
  $rockfinder = $event->arguments(0);
  $array = $rockfinder->toPlainArrayReadyForJavaScript(); // ['foo', 'bar']
  $event->return = $array;
});

This would result in this ajax response:

{
	dump: "<foo>bar</foo>",
	return: ['foo', 'bar']
}

So the console could just dump the markup and I could intercept that response with JS:

$(document).on('tracyConsoleResponse', function() {
  // get the return value of the xhr
  // render tabulator
});

Maybe that kind of refactoring could also make sense for the console? Maybe this approach could also make sense in an even bigger context: What if all panels where process modules? I for example have no idea how to build a panel for tracy (I'd have to study my hello world module again 😉 ), but it would be piece of cake to build a process module. Maybe I'm requesting too much here. But again: Maybe refactoring could make sense - I leave that assessment to you 🙂 

---

Side note: Also I have this bug when I open the console on my process module: The code of my ACE field gets quirky.

6S0Xr7M.png

That's not a request how to fix it - just to let you know why it would be great to have one central solution that can be modified instead of building our own solution and fix bugs 🙂 

 

  • Like 1

Share this post


Link to post
Share on other sites

Hey @bernhard - thanks for all the details. I'll have to get back to you on most of them, but I can explain the reason for the quirky stuff in your module. It is due to the really old version of ACE included with the InputfieldAceExtended module that you are making use of. The same thing happens with Ryan's HannaCode module - there is an issue posted about that here: https://github.com/ryancramerdesign/ProcessHannaCode/issues/21

  • Like 1

Share this post


Link to post
Share on other sites

Just had another idea that might be even more powerful and simpler to implement: What if we could define custom dumping functions? For example:

$rf = new RockFinder2();
[...]
tabulator($rf);

// modify tabulator and dump another one
tabulator($rf);

instead of a regular dump() this would render the markup of a tabulator, eg:

<div id="1905terf8dvuid"></div>
<script>
var table = new Tabulator("#1905terf8dvuid", {
 	height:205,
 	data:[
 	{id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
 	{id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
 	{id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
 	{id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
 	{id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
 	],
 	layout:"fitColumns", //fit columns to width of table (optional)
 	columns:[ //Define Table Columns
	 	{title:"Name", field:"name", width:150},
	 	{title:"Age", field:"age", hozAlign:"left", formatter:"progress"},
	 	{title:"Favourite Color", field:"col"},
	 	{title:"Date Of Birth", field:"dob", sorter:"date", hozAlign:"center"},
 	],
 	rowClick:function(e, row){ //trigger an alert message when the row is clicked
 		alert("Row " + row.getData().id + " Clicked!!!!");
 	},
});
</script>

So basically we'd only need a way to define custom functions like "tabulator()" that define the returned markup and that's it 🙂 

  • Like 1

Share this post


Link to post
Share on other sites

@bernhard

Just a little rough experimentation - I've added a new echo() method to the TD class which outputs exactly what is sent to it.

With this addition, I managed to do this:

image.png.43a3b4c134549a7238c5c1c0e19b12b4.png

Obviously in this case I am not passing any data to the tabulator() method, but you can make this happen easily by modifying your new tabulator() function.

In a process module I have a couple of things to make this all work:

1) Load the tabulator js and css files in the init() method:

        $this->wire('config')->scripts->add("https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js");
        $this->wire('config')->styles->add("https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css");

2) Define a new tabulator function - note that in this case this is a global function outside the process module class, but you could also make it a class function and call $rf->tabulator()

function tabulator($str, $title = NULL) {
    \TD::echo('<div id="tabletest"></div>
    <script>
    var table = new Tabulator("#tabletest", {
         height:205,
         data:[
         {id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
         {id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
         {id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
         {id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
         {id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
         ],
         layout:"fitColumns", //fit columns to width of table (optional)
         columns:[ //Define Table Columns
             {title:"Name", field:"name", width:150},
             {title:"Age", field:"age", hozAlign:"left", formatter:"progress"},
             {title:"Favourite Color", field:"col"},
             {title:"Date Of Birth", field:"dob", sorter:"date", hozAlign:"center"},
         ],
         rowClick:function(e, row){ //trigger an alert message when the row is clicked
             alert("Row " + row.getData().id + " Clicked!!!!");
         },
    });
    </script>', $title);
}


You can try it out by replacing the attached TD.php for your Tracy install (in the includes subfolder).

Note that you can supply two arguments to the \TD::echo method: $str and $title, just like with d() and bd()

Does that work for you ok?

TD.php

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By d'Hinnisdaël
      Happy new year, everybody 🥬
      I've been sitting on this Dashboard module I made for a client and finally came around to cleaning it up and releasing it to the wider public. This is how it looks.
      ProcessWire Dashboard

      If anyone is interested in trying this out, please go ahead! I'd love to get some feedback on it. If this proves useful and survives some real-world testing, I'll add this to the module directory.
      Download
      You can find the latest release on Github.
      Documentation
      Check out the documentation to get started. This is where you'll find information about included panel types and configuration options.
      Custom Panels
      My goal was to make it really simple to create custom panels. The easiest way to do that is to use the panel type template and have it render a file in your templates folder. This might be enough for 80% of all use cases. For anything more complex (FormBuilder submissions? Comments? Live chat?), you can add new panel types by creating modules that extend the DashboardPanel base class. Check out the documentation on custom panels or take a look at the HelloWorld panel to get started. I'm happy to merge any user-created modules into the main repo if they might be useful to more than a few people.
       Disclaimer
      This is a pre-release version. Please treat it as such — don't install it on production sites. Just making sure 🍇
      Roadmap
      These are the things I'm looking to implement myself at some point. The wishlist is a lot longer, but those are the 80/20 items that I probably won't regret spending time on.
      Improve documentation & add examples ⚙️ Panel types Google Analytics ⚙️ Add new page  🔥 Drafts 🔥 At a glance / Page counter 404s  Layout options Render multiple tabs per panel panel groups with heading and spacing between ✅ panel wrappers as grid item (e.g. stacked notices) ✅ Admin themes support AdminThemeReno and AdminThemeDefault ✅ Shortcuts panel add a table layout with icon, title & summary ✅ Chart panel add default styles for common chart types ✅ load chart data from JS file (currently passed as PHP array) Collection panel support image columns ✅ add buttons: view all & add new ✅
    • By Pip
      Hi everyone!
      I'm trying out the Login/Register module for my site. Noted that the module assigns the newly registered user to login-register role. 
      Once you modify the login-register role's permissions, particularly adding page-edit, the new member role will be set to guest. 
      Thing is I'd like to grant my new users the power to create their own pages. Any advice? 
      Thanks. 
    • By Gadgetto
      SnipWire - Snipcart integration for ProcessWire
      Snipcart is a powerful 3rd party, developer-first HTML/JavaScript shopping cart platform. SnipWire is the missing link between Snipcart and the content management framework ProcessWire.
      With SnipWire, you can quickly turn any ProcessWire site into a Snipcart online shop. The SnipWire plugin helps you to get your store up and running in no time. Detailed knowledge of the Snipcart system is not required.
      SnipWire is free and open source licensed under Mozilla Public License 2.0! A lot of work and effort has gone into development. It would be nice if you could donate an amount to support further development:

      Status update links (inside this thread) for SnipWire development
      2020-07-03 -- SnipWire 0.8.7 (beta) released! Fixes some small bugs and adds an indicator for TEST mode 2020-04-06 -- SnipWire 0.8.6 (beta) released! Adds support for Snipcart subscriptions and also fixes some problems 2020-03-21 -- SnipWire 0.8.5 (beta) released! Improves SnipWires webhooks interface and provides some other fixes and additions 2020-03-03 -- SnipWire 0.8.4 (beta) released! Improves compatibility for Windows based Systems. 2020-03-01 -- SnipWire 0.8.3 (beta) released! The installation and uninstallation process has been heavily revised. 2020-02-08 -- SnipWire 0.8.2 (beta) released! Added a feature to change the cart and catalogue currency by GET, POST or SESSION param 2020-02-03 -- SnipWire 0.8.1 (beta) released! All custom classes moved into their own namespaces. 2020-02-01 -- SnipWire is now available via ProcessWire's module directory! 2020-01-30 -- SnipWire 0.8.0 (beta) first public release! (module just submitted to the PW modules directory) 2020-01-28 -- added Custom Order Fields feature (first SnipWire release version is near!) 2020-01-21 -- Snipcart v3 - when will the new cart system be implemented? 2020-01-19 -- integrated taxes provider finished (+ very flexible shipping taxes handling) 2020-01-14 -- new date range picker, discount editor, order notifiactions, order statuses, and more ... 2019-11-15 -- orders filter, order details, download + resend invoices, refunds 2019-10-18 -- list filters, REST API improvements, new docs platform, and more ... 2019-08-08 -- dashboard interface, currency selector, managing Orders, Customers and Products, Added a WireTabs, refinded caching behavior 2019-06-15 -- taxes provider, shop templates update, multiCURL implementation, and more ... 2019-06-02 -- FieldtypeSnipWireTaxSelector 2019-05-25 -- SnipWire will be free and open source Plugin Key Features
      Fast and simple store setup Full integration of the Snipcart dashboard into the ProcessWire backend (no need to leave the ProcessWire admin area) Browse and manage orders, customers, discounts, abandoned carts, and more Multi currency support Custom order and cart fields Process refunds and send customer notifications from within the ProcessWire backend Process Abandoned Carts + sending messages to customers from within the ProcessWire backend Complete Snipcart webhooks integration (all events are hookable via ProcessWire hooks) Integrated taxes provider (which is more flexible then Snipcart own provider) Useful Links
      SnipWire in PW modules directory SnipWire Docs (please note that the documentation is a work in progress) SnipWire @GitHub (feature requests and suggestions for improvement are welcome - I also accept pull requests) Snipcart Website  

       
      ---- INITIAL POST FROM 2019-05-25 ----
       
    • By Sten
      Hello
      Till now I hacked something with the twig template but it works no more with new PW versions so I look forward to create a module. I am working on a site in multiple languages : French, English, Italian, German, Spanish, Portuguese, Hebrew, Russian. The new posts are entered in any language with a field for language. Till now, I got twig files to get the translations with constants defined for each part of the pages.
      So I'd like to create a module to include theses files added according to the url /fr/en/...
      Have you some observations to do before I begin about the direction to take ?
      Thank you
    • By ukyo
      Mystique Module for ProcessWire CMS/CMF
      Github repo : https://github.com/trk/Mystique
      Mystique module allow you to create dynamic fields and store dynamic fields data on database by using a config file.
      Requirements
      ProcessWire 3.0 or newer PHP 7.0 or newer FieldtypeMystique InputfieldMystique Installation
      Install the module from the modules directory:
      Via Composer:
      composer require trk/mystique Via git clone:
      cd your-processwire-project-folder/ cd site/modules/ git clone https://github.com/trk/Mystique.git Module in live reaction with your Mystique config file
      This mean if you remove a field from your config file, field will be removed from edit screen. As you see on youtube video.
      Using Mystique with your module or use different configs path, autoload need to be true for modules
      Default configs path is site/templates/configs/, and your config file name need to start with Mystique. and need to end with .php extension.
      Adding custom path not supporting anymore !
      // Add your custom path inside your module class`init` function, didn't tested outside public function init() { $path = __DIR__ . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR; Mystique::add($path); } Mystique module will search site/modules/**/configs/Mystique.*.php and site/templates/Mystique.*.php paths for Mystique config files.
      All config files need to return a PHP ARRAY like examples.
      Usage almost same with ProcessWire Inputfield Api, only difference is set and showIf usage like on example.
      <?php namespace ProcessWire; /** * Resource : testing-mystique */ return [ 'title' => __('Testing Mystique'), 'fields' => [ 'text_field' => [ 'label' => __('You can use short named types'), 'description' => __('In file showIf working like example'), 'notes' => __('Also you can use $input->set() method'), 'type' => 'text', 'showIf' => [ 'another_text' => "=''" ], 'set' => [ 'showCount' => InputfieldText::showCountChars, 'maxlength' => 255 ], 'attr' => [ 'attr-foo' => 'bar', 'attr-bar' => 'foo' ] ], 'another_text' => [ 'label' => __('Another text field (default type is text)') ] ] ]; Example:
      site/templates/configs/Mystique.seo-fields.php <?php namespace ProcessWire; /** * Resource : seo-fields */ return [ 'title' => __('Seo fields'), 'fields' => [ 'window_title' => [ 'label' => __('Window title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'attr' => [ 'placeholder' => __('Enter a window title') ] ], 'navigation_title' => [ 'label' => __('Navigation title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'showIf' => [ 'window_title' => "!=''" ], 'attr' => [ 'placeholder' => __('Enter a navigation title') ] ], 'description' => [ 'label' => __('Description for search engines'), 'type' => Mystique::TEXTAREA, 'useLanguages' => true ], 'page_tpye' => [ 'label' => __('Type'), 'type' => Mystique::SELECT, 'options' => [ 'basic' => __('Basic page'), 'gallery' => __('Gallery'), 'blog' => __('Blog') ] ], 'show_on_nav' => [ 'label' => __('Display this page on navigation'), 'type' => Mystique::CHECKBOX ] ] ]; Searching data on Mystique field is limited. Because, Mystique saving data to database in json format. When you make search for Mystique field, operator not important. Operator will be changed with %= operator.
      Search example
      $navigationPages = pages()->find('my_mystique_field.show_on_nav=1'); $navigationPages = pages()->find('my_mystique_field.page_tpye=gallery');
×
×
  • Create New...