Search the Community
Showing results for 'render('.
-
I think you have to do this by hand and render each page with the table. Example from the core.
-
@Ivan Gretsky, just wanted to let you know that I'm currently working on the theme feature, but it will require a bit more testing at least. Admittedly this was a bit more complicated than I had originally assumed. That being said, I've just pushed an initial version with a new "view prefix" feature to dev branch, in case you have time / want to give it a try: https://github.com/wireframe-framework/Wireframe/tree/dev. This is pretty much the first option that you described. I ended up rewriting it a couple of times, though, but hopefully have now landed on a solution that makes sense. View prefix can be set in a couple of different ways, but likely the easiest is calling Wireframe::setViewPrefix() in the bootstrap file (wireframe.php): // init Wireframe $wireframe = $modules->get('Wireframe'); $wireframe->init(); // if we're on a theme page, set view prefix if ($page->template == 'theme-home') { $wireframe->setViewPrefix('theme/'); } // render the page echo $wireframe->render(); View prefix will be used whenever Wireframe is rendering a (template/page) view file, component view file, or partial file. It should also work with separate renderer modules, but that's not something I've yet had a chance to test. At least for now default view files are used in case a prefixed version doesn't exist. This could be made configurable, but it felt more intuitive to me that this is (at least) the default behaviour. Note that in the example above I've intentionally used a prefix that is a path, e.g. has "/" — it's not necessary to use a path, it could just as well be something like "alternative-" 🙂 And a big, big warning at the end: I quite literally got this thing up and running half an hour ago. I've done very little testing, so it's entirely possible that there are still issues with it. I hope to get back to it and test properly soon.
-
Hey @Jan Romero that's true, but it shows it in a totally different way. I wanted to have a list of all methods that I can hook into, in the order of execution! I don't know how tracy sorts the list of added hooks, but it's definitely not execution order. On the other hand tracy debugger adds nice links to the hooks and shows some more information, like for RockFrontend: after RockFrontend::addAlfredStyles() AdminStyleRock::addAlfredStyles() class method 100.0 And that line does not show up in my hooks log: cat hooks.txt | grep RockFrontend ProcessWire\RockFrontend::addLiveReload ProcessWire\RockFrontend::render ProcessWire\RockFrontend::loadLatte ProcessWire\RockFrontend::addLiveReload RockFrontend\StylesArray::renderAssets RockFrontend\ScriptsArray::renderAssets Oh... that actually makes sense, because I have not had an ALFRED call on that page yet, so obviously the hookable method does not get called! 😄 I added it and boom, there it is: cat hooks.txt | grep RockFrontend ProcessWire\RockFrontend::addLiveReload ProcessWire\RockFrontend::render ProcessWire\RockFrontend::loadLatte ProcessWire\RockFrontend::getIcons ProcessWire\RockFrontend::addLiveReload ProcessWire\RockFrontend::addAlfredStyles RockFrontend\StylesArray::renderAssets RockFrontend\StylesArray::renderAssets RockFrontend\ScriptsArray::renderAssets RockFrontend\ScriptsArray::renderAssets Another one. I saved a page from the backend and the grep for "::save" looks like this: cat hooks.txt | grep ::save ProcessWire\Pages::save ProcessWire\Pages::saveReady ProcessWire\Pages::savePageOrFieldReady ProcessWire\Pages::saved ProcessWire\Pages::savedPageOrField I think this is really neat! Maybe @adrian has an idea how we could integrate this into Tracydebugger and maybe get the best of both worlds (tracy current implementation + my hacky one)? I think it would need a modification in the core, but that should not be a big deal for @ryan.
-
At first I used regions, then markup regions, and I found that I wasn't happy about performances. I did some benchmarks and noticed that the time consumed to render the page was growing faster than the amount of data to render. For example, if I double the data, rendering may take 3x the time (just a random number, I don't remember values, but I think I saved them in a text file). That's why I switched to Twig, Twig is slower for small content but is robust with big content. And I like how it's easy with Twig to write clean readable code, reuse twig fragments several times, import, extend, include, embed... there's a lot of choice, and no performance issue when including twigs into twigs. For very small html snippets that I use everywhere in the site, and are closely related to a page/template, I also have a method on my custom page classes, that calls a "Renderer" instance associated with this page and print some HTML. I use it for example for the user cards that are displayed on almost all pages of the previous site I did: <div>{{user.renderer('card')}}</div>
-
Ok. Now I got it better, I think. Now I have _init.php prepending wireframe.php that generates settings array, that I then pass to wireframe->render(). Some absolutely general settings I pass down with setting() function. If we had composers, we could move all my code in _init.php and wireframe.php to a dedicated class. Where would these composers be in places if file structure? How would we access data from them in views?
-
Exactly. Composers are useful for cases where we need to share data among different views, or certain types of views. Say, you want all your component views, partials, or perhaps field specific render files to have access to some shared data. Or you have a set of "conceptually related" templates and/or views that all need same variables. In the context of WordPress / Sage I've used this for things like shared settings, details about current session (such as user specific content, or some stats that I don't want to fetch/calculate multiple times, or in multiple locations), blocks of data that all events or news/articles share (such as a list of latest news/events), etc. You can achieve similar results via the bootstrap file (e.g. /site/templates/wireframe.php), and for some use cases it works very well. Especially when combined with utility classes or feature modules. But if there are a lot of "if template is x then..." type if-statements there, it can get a bit out of hand. Not to mention that some things are not automatically passed to all views. Anyway, the main reason I've not jumped right into this is that I'm also debating whether it truly makes sense. I do like the concept and it "feels right", and could potentially be beneficial outside of Wireframe as well. But at the same time I'm not too keen to introduce new concepts just because they sound fun 😄
-
Hi all, I've been doing some work to extend this great module created by @nbcommunication to meet a specific need we have. This is very much as-yet untested in production, but I wanted to share it here now anyway in case anyone wants to point out any flaws in the logic, try out the changes or suggest improvements before we push it to any live sites or make a PR to NB. The challenge: We manage a number of sites where we would like to get forms behind Turnstile. But in many cases these forms are connected to or hosted by third-party CRMs/Email marketing platforms etc which makes integrating Turnstile tricky and time consuming. The proposed solution: Rather than modifying a plethora of different third-party form integrations 1-by-1 and verifying submissions with Cloudflare on submit, we'll remove the forms from the DOM and only render them once Turnstile verifies the site visitor. As mentioned this is as-yet untested so I've no idea how robust this will be against bots and scrapers, but it seems worth trying IMO! In case people are wondering why we wouldn't use Cloudflare's other bot mitigation tools - we don't control all site's DNS and not all sites run behind Cloudflare. Turnstile works regardless of whether the site uses Cloudflare nameservers. The approach: I've modified the Turnstile module with a few new methods to do the following: Utilises @ryan's awesome URL hooks to create some endpoints to handle Turnstile token verification and: Dynamic loading of HTML render files into a page only once the token is verified. Use of data-attributes in page elements to specify the target location and file for rendering. Forked branch available here: https://github.com/warp-design/MarkupCloudflareTurnstile/tree/feature-protect-content-turnstile All probably best illustrated visually: Example page structure using a mix of the existing module methods and the new ones: <body> <?php //Load module in page $captcha = $modules->get('MarkupCloudflareTurnstile'); ?> <!-- Existing module widget render call. Set inside #turnstile-container to auto hide turnstile after verification --> <div id="turnstile-container"> <?= $captcha->render(); ?> </div> <!-- Elements you wish to protect with Turnstile. Set data attribute with render file path, relative to templates folder. There divs will populate with the specified render files when Turnstile verifies. --> <div class="turnstile_content" data-render-path="inc/exampleForm"></div> <div class="turnstile_content" data-render-path="inc/exampleContent"></div> <!-- New method to load the scripts if you want to protect dom elements behind Turnstile --> <?= $captcha->renderProtectedContent(); ?> <!--Existing module script call--> <?= $captcha->getScript(); ?> </body> And how this page looks live. Note: .turnstile_content elements only populate when Turnstile is verified: Test - 11 December 2024 - Watch Video Let me know what you think - is this a workable approach, or am I overlooking pitfalls? Likely issues/TODOs you may encounter: Things may need more sanitization and better error handling to come out during testing. Not sure how this will behave when loading in external JS. I've tried to ensure it will initialise any scripts in the render files when they are loaded. In theory things shouldn't be too different to loading content with frameworks or something like HTMX. Would be nice to eventually add support for passings $vars and $options params to the render files like any other PW template call. Someone may have already implemented the above in another module and I hadn't noticed! 😅
-
Hi @Alamut, You can do this with URL hook: https://processwire.com/blog/posts/pw-3.0.173/#telling-processwire-what-page-to-render Another solution is to create a template and a unique page "product-sheet" to display all your products. So the URL will always be the same except for the product ID.
-
Problem with PageReference field and hooks
bernhard replied to verdeandrea's topic in General Support
Hey @verdeandrea thx, I understood that. My question was why you only want to show "open / closed" to "courses" and "in prep / registration open" to "masters" and at the same time make it possible to add new statuses. Because that means anybody could just add "open" or "closed" which are only available under "courses" to any page under "masters" as well - which makes hiding them obsolete from a logical perspective. And if you didn't hide them, you would not have the problem that you observe. My guess would be that you want to keep the list of available statuses smaller as the global list of statuses might grow large over time? I'd probably add a custom <input> to that page reference field and hook into processInput to create the status page on my own, but only if it does not yet exist: <?php // append <input> to the page ref field wire()->addHookAfter( 'InputfieldPage::render', function (HookEvent $event) { $f = $event->object; // execute this hook only for the field in question if ($f->name !== 'your_page_ref_field') return; // append custom <input> $f->appendMarkup('<div class="uk-margin-top"> ...or create a new status:<br> <input type="text" name="newstatus"> </div>'); } ); // hook processInput to create new status wire()->addHookAfter( 'ProcessPageEdit::processInput', function (HookEvent $event) { // sanitize received status, adjust to your needs $status = trim(wire()->input->post('newstatus', 'string')); // no new status, no todos if (!$status) return; // try to find existing status page $statusPage = wire()->pages->get([ 'parent' => 123, 'title' => $status, ]); // create new status page if it does not exist yet if (!$statusPage->id) { $statusPage = new Page(); $statusPage->template = 'status'; $statusPage->parent = 123; $statusPage->title = $status; $statusPage->save(); } // set new statuspage as selected status $page = $event->object->getPage(); $page->setAndSave('your_page_ref_field', $statusPage); } );- 13 replies
-
- hooks
- pagereference
-
(and 1 more)
Tagged with:
-
Hi @adrian, Is it possible for an action to return markup apart from the successMessage and failureMessage? I'd like to use MarkupAdminDataTable to show a table of results of the action. Putting the markup in successMessage sort of works, except it has the green background so I figure it's intended for a simple sentence rather than longer markup like this. If the module doesn't already have a solution for this that I've missed, what do you think about adding a new method similar to successMessage(), or maybe if the return value of executeAction() is a string rather than boolean the module could render that under the success/failure message? Thanks for considering.
-
Went down a rabbit hole on this one... Really curious why they chose a structureless document format like markdown when there are rich and mature data standards like Schema.org. The foundational work would have already been completed, the syntax well established/adopted, and there could be a lot of areas where the wheel may not need to be reinvented. Already exists on millions of websites and generators/parsers already exist for it- adoption by devs and orgs could adopt it so much more quickly with updates to existing packages/libraries. Almost all of the examples they give on the llmstxt website could be satisfied out of the box and if not, remedied by extending the specification. Maybe I'm missing the boat on this one, but is their rejection of an existing data structure due to the fact that they want LLMs to read the content "naturally"? Are LLMs incapable? If that's the case, should LLMs be giving anyone programming tips... I know I've veered off the topic of this post, but this proposal is 3 months old and curious if it has any legs. ANYWAY. Considerations for a module... How would it handle different information at different URL paths? Would it just dump all content into a single file? May create a massive file that starts to introduce performance issues on larger sites with things like blogs. This issue filed on the proposal Github repo brings up multiple URLs but the proposal itself doesn't seem to have anything concrete that takes this into consideration. Thinking about this out loud because creating a module to satisfy this need may end up being a more generalized module. I think this would end up turning into a Markdown generator, if not a library outright. I did a good amount of searching and there are tons of PHP packages that parse MD but I couldn't find any that generate MD from values. If that library existed, the module would be a lot easier to build. In the case of this module we'd essentially be building two versions of the same site because Markdown is as concerned about presentation as it is about content rather than just logic. Each field would have to be configured for rendering in MD. The llmstxt example of Franklin's BBQ is a good illustration. They have an unordered list of weekly hours, but their menu is formatted as a table. In that example, either one could be rendered as a list or table. Assuming we are using a repeater for hours and a repeater for menu items, each field would need to have settings for how it should be rendered (list or table). In the case of a table, fields for table headers need to be mapped and the subfields in the repeater mapped to column values. I don't even know what the settings would look like to render the business hours as a list according to the example. I'm thinking that putting all of the configuration into a module would be a significant challenge. I'm not sure that this proposed standard lends itself well to creating content for the markdown file via a user-friendly UI. It may need a developer to handle it all separately. This is one of the reasons I mentioned Schema data. It would be trivial to implement a Schema object, we already to for Google's structured data. The biggest lift would be to write a library that the developer uses to render the MD data and minimizing per-field configuration, and probably making the module just a formatter that outputs Markdown using defined methods. Here's a hypothetical implementation that uses page classes and an imaginary MarkdownGenerator module. This would render something like the Franklin's BBQ example in the link above <?php namespace ProcessWire; // site/classes/HomePage class HomePage extends DefaulePage { public function renderLlmsMarkdown(): string { $md = wire('modules')->get('MarkdownGenerator'); return $md->render([ $md->h1($this->title), $md->quote($this->summary), $md->text('Here are our weekly hours'), $md->ul( array_map( fn ($row) => "{$row->days}: {$row->hours}", $this->pages->get(1012)->operating_hours->getArray(), ), ), $md->h2('Menus'), $md->ul( array_map( fn ($menuPage) => $md->link($menuPage->title, "{$menuPage->httpUrl}/llms.txt"), $this->get('template=menu')->menus->getArray(), ), ), ]); } } // site/classes/MenuPage.php class MenuPage extends DefaulePage { public function renderLlmsMarkdown(): string { $md = wire('modules')->get('MarkdownGenerator'); $markdownItems = array_map(function($menuSection) use ($md) { return $md->render([ $md->h2($menuSection->title), $md->table( ['Item', 'Price'], array_map( fn ($item) => [$item->title, $item->price], $section->menu_items->getArray(), ), ), ]); }, $this->menu->getArray()); return $md->renderBlocks($markdownItems); } } // site/init.php foreach ($pages->find('template=home|menu') as $llmPage) { $wire->addHook( "{$llmPage->url}llms.txt", fn (HookEvent $e) => $e->pages->get($llmPage)->renderLlmsMarkdown() ); } That should really leverage caching in the real world. This approach will render an llms file at each individual URL for pages that are configured. This standard proposal seems to be taking a non-web approach and, as mentioned in that Github issue above, haven't considered leveraging web URLs but instead creating a stack of separate linked MD documents that an LLM reads like a book at the root URL. Since the standard doesn't say "look for llms.txt at every available url', then any pages with llms data will have to be specifically referenced/rendered on either the root llms.txt document or another llms.txt document that is or has an ancestor that is referenced in the root document. This follows the BBQ example, but just uses actual URLs rather than generating a stack of separate MD documents at the root. I assume you could just hook file names that contain Page IDs or something, but this makes more sense to me. Seems like an incredibly efficient way to build a whole new internet just for robots without any value provided to the people doing the work 🤔 At the very least I want a promise from someone that my life and the lives of my family will be spared when Skynet takes over. tl;dr Creating a module specifically to render llms data may not be the most efficient way to go about this A module that puts configurations into the UI would have to be extremely complex and account for the many types of fields available in ProcessWire Accounting for fields requires that each type of field is limited to the type of MD is can generate if the module attempted to make everything configurable The best way would probably be to create fields that will contain the content and then have your code do the rendering This is basically just creating two websites. One for people and one for LLMs Because this proposed standard has chosen markup over a logical data structure, it's probably always going to be on the shoulders of the developer unless they change something Another challenge is their expectation of additional content management: If this is important enough then there may be a need to manage LLM consumable information separately in fields that contain content sufficiently dumbed down for LLMs. Maybe the real module here is one that connects to an LLM API which auto-summarizes the content to then be used when creating MD files that describe the content to other LLMs. Solution: a library or Module that takes inputs and renders Markdown. Wouldn't be anything specific to AI. Or this standard could be tossed and we can just render structured data on the web page so LLMs can use the internet as a natively hyperlinked set of documents located at stable and discoverable URLs... Having thought this out I think even less of this standard than when I first read the proposal 🤣
- 1 reply
-
- 2
-
Or maybe this edited code of your first post works? $map = $modules->get('MarkupLeafletMap'); echo $map->getLeafletMapHeaderLines(); $mappoints = new PageArray(); foreach ($page->map_repeater as $point) { $mappoints->add($point) // the repater is a page } echo $map->render($mappoints, 'your_map_field_name', array('height' => '270px')); ?>
-
Hi @torf, maybe I didn't get it at all or maybe I didn't explain well my idea. So I'll try again... 😉 Surely I could be wrong, but for me a PageArray is not only for admin side, but all the pw pages collected into a php variable created with pw selectors in a script file. For shortness I have created 2 pages with two repeaters each (repeater name is "multipoints"), with a title and a leaflet map field (named 'fm_mappa') into. This is the simply code for testing. Please note that I didn't get the repeater with a foreach statement, but with a pw search with a selector for all the templates with name equals to "repeater_NAMEOFTHEREPEATER", as pw builds. Obviously into your selector you can build your search to the desired points, e.g with sorting or something other. echo $pagesWithMultipointsRepeater = wire('pages')->find('template=repeater_multipoints'); if (count($pagesWithMultipointsRepeater)){ $map = $modules->get('MarkupLeafletMap'); $options = array( 'height' => 800, 'markerColour' => 'red', ); echo '<div class="g-mb-25">'; echo $map->render($pagesWithMultipointsRepeater,'fm_mappa',$options); echo '</div>'; } The numbers before the map are the repeater ids (note the "echo" on the first line of the code). And these are the admin pages: I hope that's clearer.
-
Hi @torf Never used Leaflet Map with repeaters, but in past I had to collect lot of points into a single map. I simply used a PageArray with wire('pages')-find('template=MY_TEMPLATE, and so on...') and then I passed the PageArray to the $map->render($MY_PAGE_ARRAY, 'MY_MAP_FIELD', $options); it works. So I suggest to collect your points in a PageArray with proper selectors. Don't forget that your repeater has a template, and if useful you can get the parents of them. Let me know if this solution can fit your needs.
-
Hi, does anybody know how to use the module with a repeater? I need to have multiple mappoints in one map at my frontend, and due to the nature of the site I cannot put them in pages. So I thought of using a repeater for those points (as it is not possible to add multiple markers to one map). In the backend it works fine, but I cannot figure out how to collect those points and display them in one map. <?php $map = $modules->get('MarkupLeafletMap'); echo $map->getLeafletMapHeaderLines(); $mappoints = []; foreach ($page->map_repeater as $point) { array_push($mappoints, $point->map); //or array_push($mappoints, [$point->map]); //or array_push($mappoints, $point->map->LeafletMapMarker); array_push($mappoints, [$point->map->lat, $point->map->lng]); } echo $map->render($page, $mappoints, array('height' => '270px')); ?> All I tried gave me different mistakes. Does anybody know the correct syntax?
-
Handling a callback from an API
TwoWheelDev replied to TwoWheelDev's topic in Module/Plugin Development
Time to answer my own question... and love it or hate it AI came up with the goods on this one! Defining the urlHook as follows: public function init() { $this->addHook('/custom-url/', $this, 'handleCustomURL'); } And the handleCustomURL function (this was the second iteration I got for this to include having a default template in the module, whilst allowing them to be overridden in the site/templates/ folder): public function handleCustomURL(HookEvent $event) { // Path to the override template in the site's templates directory $overrideTemplatePath = $this->config->paths->templates . 'custom-template.php'; // Path to the default template in the module's directory $defaultTemplatePath = $this->config->paths->siteModules . $this->className() . '/templates/custom-template.php'; // Determine which template to use $templatePath = file_exists($overrideTemplatePath) ? $overrideTemplatePath : $defaultTemplatePath; // Check if the determined template exists (for safety) if (!file_exists($templatePath)) { throw new Wire404Exception("Template not found"); } // Render the template and pass variables $output = $this->files->render($templatePath, [ 'someVariable' => 'someValue', // Add additional data if needed ]); // Output the rendered content echo $output; // Stop further processing $event->replace = true; } I did make a small to change to the end of the function as follows: // Output the rendered content //echo $output; return $output; // Stop further processing - Doesn't look like this is needed! // $event->replace = true; } Not sure any amount of Google-Fu would have got me to this, so it's interesting to see how AI can pull the correct bits of information together! I have obviously tested the above code, and it seems to work a treat! -
module PrivacyWire - Cookie Management & async external asset loading
2hoch11 replied to joshua's topic in Modules/Plugins
…I made an TextInputField (site_setup_cookiebox_toggler_text) Then in the "Details" tab: Text Formatters > PrivacyWire Textformatter I added this field to the home template. Then I pasted this [[privacywire-choose-cookies]] in the text field. The outputted the field content for the frontend: $pages->get('/')->site_setup_cookiebox_toggler_text It works but I wantet this in the template (without that workaround). I tried this, but no luck: $privacyWire = $modules->get('TextformatterPrivacyWire'); echo $privacyWire->render("[[privacywire-choose-cookies]]"); What was your solution? -
To do this I think you'll have to hook the rendering of the repeater item, which is a fieldset: $wire->addHookBefore('InputfieldFieldset(name^=repeater_item)::render', function(HookEvent $event) { $inputfield = $event->object; $inputfield->label = $event->wire()->sanitizer->unentities($inputfield->label); });
-
I keep getting this error message on all backend and frontend pages in one of my projects: ErrorException: Undefined array key 1 in /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/panels/TracyLogsPanel.php:71 Stack trace: #0 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/panels/TracyLogsPanel.php(71): Tracy\Bar->Tracy\{closure}(2, '...', '...', 71) #1 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(142): TracyLogsPanel->getTab() #2 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(115): Tracy\Bar->renderPanels('') #3 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(89): Tracy\Bar->renderPartial('...') #4 /var/www/html/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Debugger/DevelopmentStrategy.php(123): Tracy\Bar->render(Object(Tracy\DeferredContent)) #5 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Debugger/Debugger.php(314): Tracy\DevelopmentStrategy->renderBar() #6 [internal function]: Tracy\Debugger::shutdownHandler() #7 {main} I am using the newest PW Version and the newest Tracy Debugger Version, can anybody give me a hint what is happening here?
-
Hi @bernhard we just updated RockFrontend on a site from 3.20.0 to 3.23.3 and the site stopped working. I fixed it by changing templates/_main.php <?= $rockfrontend->renderLayout($page); // worked before update ?> <?= $rockfrontend->render($page); // works after update ?> We use RockPageBuilder and in templates/sections/main.latte <div sortable x-ref="additional-sections"> {$page->get('rockpagebuilder_blocks')->render()|noescape} </div> Now after the update that threw an error on our home page because template home has no field rockpagebuilder_blocks I am wondering why this is. Do you have any idea? I looked at the function signature for render() and the examples in the PHPDoc do not mention that we can pass a Page object as $path argument. So I thought we could not call render($page) at all. But it works. I guess because $page is then overwritten with $this->wire->page. So renderLayout($page) would be the correct method to use. But something in the inner workings of renderLayout must have changed and stopped the site from working. I suspect that the way we have setup rendering with RockPageBuilder, RockFrontend and Latte is fundamentally wrong.
-
Hi, "funny" enough i think the error comes from the way npm import the files (or the way dependencies are written in the files) as, if you have a close look at where the error is it's in the daygrid index.js file line 1 when using a importmap like in this example but with the map aiming at the files imported with npm (it works fine with the distant files) https://fullcalendar.io/docs/initialize-browser-esm i've also tried a more "old" and "brutal" way of woking using curl to get locally https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.js using it as a simple js file once in my assets/js/ folder and the main script in a simple js file (not a module one) and everything went well too, my usual a little tricky usages as well as your own script except thet the instance is slightly different document.addEventListener('DOMContentLoaded', function () { const calendarEl = document.getElementById('calendar') const calendar = new FullCalendar.Calendar(calendarEl, { initialView: 'dayGridMonth' }) calendar.render() }) thank you actually as you convinced me to keep working this old way with fullcalendar 😀 have a nice day
- 17 replies
-
- 1
-
- javascript
- js
-
(and 2 more)
Tagged with:
-
I know this is not exactly ProcessWire related, but it's still an issue I'm facing while trying to implement in a PW site. I'm trying to get Fullcalendar to work, first I included it via CDN, which worked OK, but then I wanted to implement the rrule plugin which always threw an error that I just never managed to resolve. Then I switched to installing it via npm, not least because in the long run I would like to have Fullcalendar be served locally anyway, which is the best practice (?). I followed the instructions on www.fullcalendar.io concerning the implementation via npm: import { Calendar } from '@fullcalendar/core/'; import dayGridPlugin from '@fullcalendar/daygrid'; import timeGridPlugin from '@fullcalendar/timegrid'; import interactionPlugin from '@fullcalendar/interaction'; document.addEventListener('DOMContentLoaded', function() { const calendarEl = document.getElementById('calendar') const calendar = new Calendar(calendarEl, { initialView: 'dayGridMonth' }) calendar.render() }) But the calendar does not render and I keep getting this error: Uncaught TypeError: Failed to resolve module specifier "@fullcalendar/core/". Relative references must start with either "/", "./", or "../". FYI I'm using webpack to bundle it and entry and output points seem to work fine. All node_modules are visible in the file system. I don't use any framework like react, just vanilla js. Error occurs on Chrome, FF and Safari Help is very much appreciated, I already lost a couple of days over this 🙈
- 17 replies
-
- javascript
- js
-
(and 2 more)
Tagged with:
-
[Solved] RPB render allocation with site-rockfrontend profile
olivetree replied to olivetree's topic in RockPageBuilder
Hi @bernhard. I apologize for not being so specific, you're absolutely right. I just wanted to bring RockPageBuilder working with site-rockfrontend profile. Just to reflect. I can not recover every step anymore, but after installing and setup as in docs RPB was only shown with its functions on the home page, but not on basic-page. I was muddling around in tempaltes directory and tried dozens of combinations or single entries in single and/or in many template php files or in latte files with those snippets. PHP <?= $rockpagebuilder->render(true) ?> or Latte {if $page->template == 'basic-page'} {$rockpagebuilder->render()} {/if} or {$rockpagebuilder->render()} Yes there were red errors instead of fixing them. Then I just reinstalled pw with all modules needed. I've learnt so many aspects about PW, several rock-modules and site-rockfrontend profile and their structure. I know that is not a systematic and specific (not a best) way. I just wanted to have RockPageBuilder and site-rockfront having up/running, using an unstructured try and error workflow. -
[Solved] RPB render allocation with site-rockfrontend profile
olivetree replied to olivetree's topic in RockPageBuilder
Many thanks @bernhard for your hints. Now it works. For me it was unclear where to put the render() snippet in, I understood where it I tried several files, but now it works. In the RockPageBuilder doc you mention using the site-blank profile, where all works, but I like the delayed output defined in site-rockfrontend. -
Module: AIOM+ (All In One Minify) for CSS, LESS, JS and HTML
hellomoto replied to David Karich's topic in Modules/Plugins
In the document html head tag: if (!empty($jshead)) echo '<script src="'.\AIOM::JS($jshead).'"></script>'; if (!empty($jsfoot)) echo '<script src="'.\AIOM::JS($jsfoot).'" defer></script>'; ... both lines render the same file, containing only one of the files in the respective arrays (each array has one item, it only contains the 1st)? What am I doing wrong? Also, including @import google fonts begets the following error: PHP Warning: Trying to access array offset on value of type null in .../processwire/site/modules/AllInOneMinify/lib/Less/Less.php:5746 No error if I include the compiled CSS instead of LESS, but @import is used in the README examples?