-
Posts
7,529 -
Joined
-
Last visited
-
Days Won
160
Everything posted by kongondo
-
Let's start from here: No. you don't have to use Alpine.store(). However, store comes with some advantages as explained here and here. I prefer to use the store, maybe due to vuex influence. Not sure. When do you want to release it? Soon? Then I'd release it and refactor it later. A potential challenge here is that you may not find the time 'later' to refactor it ?. Do you have to use Alpine JS? No you don't. Personally though, I will be removing jQuery from everything I've built. It will take time though. This has nothing to do with the new tech such as Alpine really, but I now prefer to use vanilla JS and/or Alpine/Vue, etc. Modern vanilla JS syntax is just clearer to me. Anyway, I digress. Using reactive frameworks, you would have at least two options: #1. model the value: E.g. v-model or x-model in vue and alpine respectively. This two-way data bind means you don't have to listen to the on change event. That will be taken care for you, unless you also want to listen to the event and do something based on that. This approach will also trigger changes in other areas of the app that depend on the changed value. Your data will be changed (instead of the input value) and behind the scenes vue/alpine will change the value of the input for you. Everything stays in sync. By the way, if you want one-way bind, have a look at x-bind:value #2. on:handler: You handle the event yourself. E.g. with Alpine, @click='doSomethingWithClick' or x-on:click='doSomethingWithClick'. In this case as well, the idea is generally to modify your data based on some event INSTEAD OF modifying the input value directly based on the event. If you modify the data, you are back to #1, where everything is synced for you. Using Alpine, you won't need to work with the JSON object. You will be working with JavaScript objects, arrays, bools, etc. You won't have to do this. If modelling your data (x-model) to inputs, Alpine will update your data for you automatically. Your work will be to validate values and check other app states if required. This is very easy to do with Alpine/Vue. Just use an @click handler and handle that. I could give you a basic example but I would prefer to see your use case/code example as you might not need the click handler at all. As mentioned above, you don't have to do this yourself. Let x-model take care of it for you. When the form is saved, it will save with the modelled values. E.g. <input type='text' name='your_name' x-model='person_name'/> In the above example, when you type into the input box, Alpine will update the value of person_name to what you input. If you want to see it live as you type, you could do: <input type='text' name='your_name' x-model='person_name'/> <p x-text='person_name'></p> The text inside the paragraph will be synced to and output the current value of 'person_name'. I would need to see this in action to get my head around how you would model it in Alpine ?. Data You have a number of choices to pass your data from ProcessWire to your Alpine app. $config->js If your data was static, you could use ProcessWire's config->js to get it populated in the browser. E.g, send the current page ID or the URL to some backend API, etc. You could then access these in your JS code/Alpine as, e.g. // configs object const configs = ProcessWire.config.InputfieldPageBuilder Inline Script You can have your inputfield, in render(), output inline script that has your data. This is useful if you data is dynamic. You can see this usage in ProcessWire, e.g. in InputfieldRepeater. E.g. <?php // e.g. inside ___render() $data = ['age' => 24, 'gender' => 'female', 'department' => 'design']; $out = "<p>Some Inputfield Render Output</p>"; $script = "<script>ProcessWire.config.InputfieldPageBuilder = " . json_encode($data) . ';</script>'; $out .= $script; return $out; You can then access access the data as in the configs object in JS above. Inline x-data Attach your data directly to the x-data value in ProcessWire markup. JSON or 'object' (e.g. a string that resembles a JavaScript object) both work. <?php $json = json_encode(['age' => 27, 'gender' => 'female', 'department' => 'ai']); $out = "<div x-data='{$json}'><p x-text='age'></p></div>"; return $out; In all of the above, you don't need this: Or this: Is there a reason you are using Alpine as a module here? I'd probably send this data to the browser using an inline <script> instead of as a value of '#Inputfield_pgrid_settings'. Just makes life easier. I would then set the data as a property in my Alpine.data() or in Alpine.store(). Quick Tips If using $store inside a ProcessWire module, I create a class property and set my store value to it. Then, I only have to call it like this where I need it: $this->xstore. Saves with typing plus change it once, change it everywhere. In JS, I use getters and setters, either separately or combined into once function to handle data and store values. Saves from typing this.$store.mystore.settingsData.someValue = 1234, all the time. E.g. // below could be converted to single getter/setter methods // could also be adapted to handle nested properties or create separate methods for such setStoreValue(property, value){ this.$store.mystore[property] = value; } getStoreValue(property){ return this.$store.mystore[property]; } Hope this helps.
-
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
Glad you got it sorted...? Until you didn't...? Please open a separate thread, maybe under dev talk as this is about Alpine. We'll then continue this conversation there, thanks. -
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
In the beginning it was too fast for me! I couldn't notice that a change had taken place ?. -
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
Do you have a reference or is it from personal experience? Have you seen this discussion and/or x-ignore? I don't want to derail the topic in this thread though, so we might have to hive off this talk. ?. Edit: A reference to a similar issue to @dotnetic's -
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
If you go the Vue route, the easier way is to let it create the inputs but also assign usual ProcessWire classes to them, which then, would be picked up by ProcessWire styling when rendered. However, you will need the full house of markup including the wrappers somewhere wrapping the Vue-generated inputs. Otherwise, some ProcessWire styles might not be applied. Some label inputs might not appear, etc. Better to use Alpine if you can. -
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
Then Alpine JS it is ?. Learn Vue, say thanks to the creators then say hello to Alpine JS. You will write its code right inside your ProcessWire inputfields, markup, whatever. Everything will be reactive. Make use of Inputfields->attr to assign Alpine properties. You might need the full attribute, e.g. 'x-on:change' instead of @change as ProcessWire might strip the latter out. Below is a quick example. I haven't checked it for errors. Inside your ProcessWire code. <?php // get a ProcessWire inputfield wrapper $wrapper = new InputfieldWrapper(); // get an inputfield text to store a name $field = $this->modules->get('InputfieldText'); // add some usual field values $field->name = 'your_name'; // OR // $field->attr('name', 'your_name') // etc... // let's alpinejs-it! $field->attr([ // MODEL THE VALUE DIRECTLY IN THE STORE // 'x-model' => "\$store.mystore.person.name", // OR HANDLE THE CHANGE YOURSELF // @note: ProcessWire will strip out the '@' - so we use x-on:event instead 'x-on:change' => "handleNameChange",// this is a method inside your Alpine data code ]); // IF YOU NEED TO.... // set a wrapper-level class, e.g., as a show-if // @note we escape some things here, e.g. the $ // could also use JavaScript template literals for the 'some_text', e.g. `some_text` // here we add a hidden class to the wrapper depending on some store value // we could have used x-show or x-if instead $class = "{ hidden: \$store.mystore.some_text==\"some_text\"}"; $field->wrapAttr( 'x-bind:class', $class, ); $wrapper->add($field); // initialise alpine js data // 'persons' could also be an object here, but for more complex objects, better to assign to a function in your code like this $out = "<div x-data='persons'>" . $wrapper->render() . "</div>"; return $out; You JavaScript // ALPINE (version 3+) document.addEventListener("alpine:init", () => { Alpine.store("mystore", { // YOUR STORE FIELDS // for some results results: [], some_text: "some_text", is_modal_open: false, person: {}, }) Alpine.data("persons", () => ({ handleNameChange(event) { this.changeCustomerName(event.target.value) }, changeCustomerName(name) { this.$store.mystore.person.name = name } })) }) Hope this helps. -
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
One is in the works....still in my head though...as I clear my in-tray first! (you know what I'm talking about ?). Yes and yes. If you are using Vue 2, there is a post somewhere in the forums (@elabx, help please, thanks) with a copy-amend-paste code from WP. That code will enable live reload in ProcessWire backend but view will still need to be running on some other port, e.g. 3000. However, you won't have to keep an eye on that as you will be viewing the changes in the ProcessWire backend. I have since adopted Vue 3 and Vite and the live reload in ProcessWire is as simple as this: <?php // e.g., in execute() if developing a Process Module $out = " // 3000 is the port vite is running at $out .= ' <script type="module" src="http://localhost:3000/@vite/client"></script> <script type="module" src="http://localhost:3000/src/main.js"></script>'; //return $out; if in a method/function Vite does not use Webpack. So, no (crazy) Webpack configs needed! The live reload just works! Having said that, I highly recommend Alpine JS (as a Vue alternative, if you can get away with it) and HTMX (no Axios, no JSON!). With either, no build is required! You keep your DOM and work right inside ProcessWire. Future tutorials in the works, as well ?. If you understand Vue then you already understand Alpine JS. If not, I still suggest you get to know the basics of Vue anyway. Hope this helps. -
True, but not applicable to usage of ProcessWire itself unless something's changed ?.
- 4 replies
-
- 2
-
-
- security
- injections
-
(and 2 more)
Tagged with:
-
Works here just fine. I don't even have to manually load its assets. All of the below work. <?php $field = $this->modules->get('InputfieldDatetime'); $field->inputType = 'text'; $field->datepicker = 3; // $field->datepicker = \ProcessWire\InputfieldDatetime::datepickerFocus; //$field->datepicker = InputfieldDatetime::datepickerFocus;
-
@howdytom, Glad you like the module. There is a defaultOptions but it doesn't cover your rel and anchor tag title needs. I highly suggest you use the getMenuItems() method to build your menu and customise it however you wish. There are a number of examples at that link. Please let us know if you need further assistance.
-
Best method to render page content within a modal?
kongondo replied to gornycreative's topic in Getting Started
@Jonathan Lahijani's strategy is quite good. Here are a few more HTMX + $config->ajax options: 1. hx-headers (docs). Quick and dirty addition of X-Requested-With: XMLHttpRequest to the headers. As per the docs, make sure to use the valid JSON option AND NOT the JavaScript eval(). Example: <?php namespace ProcessWire; // define variables $someURL = '/some-url/'; $XMLHttpRequestJSON = json_encode(["X-Requested-With" => "XMLHttpRequest"]); $out = "<div hx-get='{$someURL}' hx-headers='{$XMLHttpRequestJSON}'>Get Some HTML</div>"; // use $out... The disadvantage here is having to add the headers manually to all the markup that need it. I think it could be added to body but from what I recall, there are disadvantages to adding attributes to the body tag? Maybe someone could confirm/disapprove this. Yes. hx-headers can be added to the body tag. Edit: From the docs... hx-headers is inherited and can be placed on a parent element. A child declaration of a header overrides a parent declaration. 2. The ajax-header Extension (docs) Here you will need to include the tiny (7 lines of code) extension ajax-header.js script to your HTML. You can then issue ajax requests as usual like shown below using the hx-ext attribute. <?php namespace ProcessWire; // define variables $someURL = '/some-url/'; $out = "<div hx-get='{$someURL}' hx-ext='ajax-header'>Get Some HTML</div>"; // use $out... 3. htmx:configRequest (docs) Use JavaScript to configure the request. This one is a bit more involved but gives you greater control than #2. In this example, we assume you have a main.js file that you include in your template(s) file(s). Inside main.js, add the code as shown below. // main.js // DOM ready document.addEventListener("DOMContentLoaded", function (event) { // init htmx with X-Requested-With initHTMXXRequestedWithXMLHttpRequest(); }); function initHTMXXRequestedWithXMLHttpRequest() { document.body.addEventListener("htmx:configRequest", (event) => { // if you wish to add CSRF checks. here token added to headers // but you can also add to request using hx-vals, for example. // const csrf_token = getCSRFToken(); // event.detail.headers[csrf_token.name] = csrf_token.value; // add XMLHttpRequest to header to work with $config->ajax event.detail.headers["X-Requested-With"] = "XMLHttpRequest"; }); } function getCSRFToken() { // find element, e.g. hidden input, with id '#_post_token' // it holds our token name and value const tokenInput = htmx.find("#_post_token"); return tokenInput; } Then in your template file: <?php namespace ProcessWire; // define variables $someURL = '/some-url/'; $out = "<div hx-get='{$someURL}'>Get Some HTML</div>"; // use $out... -
Are any of the methods here helpful? https://processwire.com/api/ref/markup-pager-nav/ Especially, setBaseUrl(), setQueryString(), setGetVars() Not sure if it is applicable here but in the past I've had to append ?pageNum=1 to the URL of page 1. $input->queryString() might also be helpful to handle your channel strings?
-
@horst This is a Pageimage object. $photo->mediaField; This is a Pageimages object. https://mediamanager.kongondo.com/documentation/frontend-output-of-media-manager-fields/media-manager-objects/
-
Most likely a Textformatter module. I don't know if there is one already in the module's directory. You might need (to make) a custom one. Sorry, in a hurry, but hopefully this gets you started...
-
There is no variable value in this module's API. The page id is at the variable info. So: <? php $pageReferencedByMarker = $pages->get((int) $dot->info); // do something with $pageReferencedByMarker
-
$session object unavailable in PHP function in template
kongondo replied to ErikMH's topic in General Support
Just read this quickly... ProcessWire variables such as $config, $session, $page, etc need to be accessed differently inside functions (check out PHP function scope). One way to access them is via wire, e.g. wire('config'), wire('session'), wire('page'), etc. ProcessWire variables are already global. I don't understand why you are using the PHP global keyword. Others will chime in, with better answers ?. -
Glad you got it sorted :-). I have never used srcset myself (I think it is a third-party module?) but this should work since media is a Pageimage object in this case. This is used in the ProcessWire sense of image variations as briefly explained here. Whilst you can certainly utilise variations for responsive designs, they are not limited to that use.
-
Many thanks for the purchase. This is because your PortfolioImage is not a file or image field. It is a textarea field. Textarea fields do not have a url property. It is not clear to me how you want to display your MM image (i.e. inside a textarea, e.g. CKEditor) or independently of the textarea (i.e., some_media_manager_field->url). I am not sure if you have seen Media Manager's documentation? If not, please have a look at that first. Thanks.
-
Hi everyone. It's been a while. A little update. There has been a delay, again, unfortunately! Lockdown hit really hard. There were also a number of technical issues but these have since been resolved. Finally, a number of you (having seen the preview videos) strongly expressed the need for the Padloper UI to resemble the ProcessWire admin theme even in the alpha stage. The message I got was that this was more important to them from the get-go than having advanced Padloper features. I accepted their reasoning but this came at a cost. Padloper 2 has been re-themed to look like the ProcessWire admin. Given that we are using third-party libraries to build Padloper 2, this took a lot of time. Focus was placed on basic features only, for now, in order to expedite the first release of Padloper 2. This means that some advanced features will be missing from the first release of Padloper 2. As for a release date, I was hoping for a 'spring baby'. That won't happen. I am now working hard toward a 'summer baby'. Screenshots Have a nice and safe day.
-
Great! I have a feeling Windi CSS might have been a wakeup call ?.
-
Not on a site, but I have noticed something similar (If I recall correctly), when approving comments sent to me by ProcessWire for approval with respect to comments left on my modules' pages in the modules directory (hope this makes sense...Friday, tired and all that ?).
-
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
Aha! The tut I intend to write will explain what all those options do (although the WordPress tut has some good explanations as well). -
Module Module: Matrix Fieldtype & Inputfield
kongondo replied to kongondo's topic in Modules/Plugins
Just think ProcessWire page reference fields ?. -
Integrate Vue.js in a ProcessWire module
kongondo replied to dotnetic's topic in Module/Plugin Development
Same here! This one. Hehe. Tell me about it! -
Module Module: Matrix Fieldtype & Inputfield
kongondo replied to kongondo's topic in Modules/Plugins
I see. Have you tried with the Custom PHP Code options? I haven't touched this in a while but (in my head) it seems like it is doable.