Leaderboard
Popular Content
Showing content with the highest reputation on 10/29/2017 in all areas
-
Another option for adding elements at the end of <head>: $wire->addHookAfter('AdminTheme::getExtraMarkup', function(HookEvent $event) { $parts = $event->return; $parts['head'] .= "<script src='/path/to/script.js'></script>"; $event->return = $parts; });3 points
-
@bernhard Here is the code I used on site/ready.php and it works great: if($this->page->template == 'admin') { $this->addHookAfter('Page::render', function($event) { $css = wire('config')->urls->templates . 'styles/AdminThemeUikit.css?v=1'; $js = wire('config')->urls->templates . 'scripts/AdminThemeUikit.js?v=1'; $event->return = str_replace("</head>", "\n<link type='text/css' href='{$css}' rel='stylesheet'/>\n</head>", $event->return); $event->return = str_replace("</body>", "\n<script type='text/javascript' src='{$js}'></script>\n</body>", $event->return); }); }; I've also uninstalled Admin Custom Files since I was only using it to inject theme files. Thank you.3 points
-
You can also inject scripts and styles by hooking the page render and doing a str_replace("</head>", $yourscripts . "</head>", $event->return)3 points
-
FieldsetTab is not supported by the core "show if" dependency, but it turns out it is possible to support it in this module. Please update to v0.0.5.3 points
-
Hi @Monty and welcome. I'm not 100% sure how you make just one part of a site powered by processwire. Maybe see this older thread where they talk of something similar: It might actually be easier to integrate processwire into the entire site. Then you can add your gallery easily, plus you'd have a nice CMS to boot for making any future changes. It sounds way more difficult than it actually is. You can convert existing HTML themes to processwire easily, so your static site would be no different. Whichever way you decide to go, just post in here and you'll have all the help you need.2 points
-
2 points
-
I may be wrong but the problem is most likely due to this line. With single quotes, $evName is interpreted literally, so you get errors trying to create the same page again, and don't notice it because you probably have the debug mode off as @Robin S pointed out. Also, <?php namespace ProcessWire; foreach ($events as $event) { // you don't have to manually clean up strings to create page names, just use $sanitizer $evName = $sanitizer->pageName($event['name']); $p = $pages->get("/events/$evName/"); if (!$p->id) { $p = new Page(); $p->template = 'basic-page'; $p->parent = '/events/'; // $p->name = '$evName'; // single quotes -> interpreted as literal string $p->name = $evName; } $p->of(false); $p->title = $event['name']; $p->save(); } ?>2 points
-
Let's do a comparison of how you would do this with the typical delayed output approach vs Markup Regions. When it comes to the Markup Regions example I'll do it a little differently than you've proposed it, with a dedicated <region> for scripts instead of appending to <head>. Delayed output _init.php $scripts = ''; _main.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <?= scripts ?> </head> //... template-which-needs-js.php if(strpos($page->name, 'special') === 0) { $scripts .= "<script src='{$config->urls->templates}assets/js/my-script_2.js'</script>"; } else { $scripts .= "<script src='{$config->urls->templates}assets/js/my-script_1.js'</script>"; } Markup Regions _init.php Nothing needed here because one of the nice things about Markup Regions is that you don't need to initialise a markup variable. _main.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <region id="scripts"></region> </head> //... template-which-needs-js.php <region id="scripts" pw-append> <?php if(strpos($page->name, 'special') === 0): ?> <script src="<?= $config->urls->templates ?>assets/js/my-script_2.js"></script> <?php else: ?> <script src="<?= $config->urls->templates ?>assets/js/my-script_1.js"></script> <?php endif; ?> </region> So comparing a markup region to a variable: Use pw-append where you would have used $some_var .= 'something' Use pw-prepend where you would have used $some_var = 'something' . $some_var Use neither pw-append nor pw-prepend where you would have used $some_var = 'something' But Markup Regions are even more powerful because you can have multiple nested markup regions in _main.php, which is something you cannot do with variables.2 points
-
As said before, I don't know Twig that much, but with PHP it's not that much uglier. PHP is a template language in itself, imho. Here's the equivalent (well, it should work ;-): <?php foreach ($page->exhibition_artist as $artist): ?> <?=$artist->title;?> <!-- Show works that are related to current exhibition and belong to a given artist --> <?php foreach ($pages->find("template=work, work_exhibition=$page->path, work_artist=$artist") as $work): ?> <?=$work->title;?> <?php endforeach;?> <?php endforeach;?>2 points
-
Hey! When I was building a little commercial Processwire website for a family member, I started looking into caching with WireCache and somehow had troubles to find a satisfying solution to organize the caches and their expirations. My site had a few parts that updated in a regular manner while other parts should be refreshed whenever the current page - or e.g. for the menu: any page - was saved. I wanted to create a cache of the whole page's html which should expire whenever any of its parts expired. This would be simple if you could set multiple expire values for one cache. Unfortunately, you can only set one. So I started to build a solution to my problem which uses the WireCache and creates a dependency tree for every cache. And since I haven't yet implemented a Processwire module and this little class might be useful for other websites, too, I thought I'd try to make a module out of it. This is it. Github: https://github.com/janKir/CacheNesting Please have a look, and feel free to leave a comment. This is my first module, so any suggestions are welcome. I am not even sure if my approach makes much sense for performance reasons. I'm happy to hear your opinions! Thanks a lot!1 point
-
1 point
-
never used it but you could save another line with conditional hooks https://processwire.com/blog/posts/new-ajax-driven-inputs-conditional-hooks-template-family-settings-and-more/#new-conditional-hooks $wire->addHookAfter('Page(template=admin)::render', function($event) { ... });1 point
-
No problem. I have a solution in place on your site, but I need to test a little more before releasing, so I would appreciate it if you could keep my account active for a while still. Take a look though - now you'll finally see what the Captain Hook panel is all about1 point
-
Thanks - I have figured out the issue - it's to do with the path of your site, which starts with: /home/.sites/ which that strpos($path, '/.') === false is catching. I'll get a fix out shortly, although I have to leave in a few minutes, so it might be better if I don't rush and leave it till later today or tomorrow. Thanks again for access to your site - we could have gone around in circles for hours otherwise1 point
-
Ok, i figured it out. Adding $paths = array(); before the foreach start solves the problem. So it seems that if $path is not defined as an array before the foreach, it doesnt work. So the complete code is like this: $paths = array();//this solves the problem foreach ($iter as $path => $dir) { // '/.' check is for site module backups - SKIP_DOTS above is not excluding these if (!$dir->isDir() && strpos($path, '/.') === false && preg_match($fileNamePattern, $path) && !in_array(basename($path), $excludeFilenames) ) { $paths[] = $path; } } return $paths; Best regards1 point
-
I am getting a little OT, but it's possible to support commas and complex data types in CSV with a proper CSV parser. PHP's native ones are not great. I make use of https://github.com/parsecsv/parsecsv-for-php in a couple of my modules. It's an older library that doesn't appear to be maintained anymore. I think there might be better ones out there, but at the time it handled everything I needed better than anything else I found. Back to the topic at hand - I am curious about a feed of 1300 pages - that could definitely take a little while to process. It's a shame it's not just addition of new pages - you could make that very quick if the xml feed entries had a date. But if you have to process them all for updates and deletions, you will be relying on the title of the page for matches. Will you just update them all, or will you compare the contents of fields for differences and process only if there has been a change?1 point
-
1 point
-
That's the organisation pricing. You're an individual customer so it's $89. And you don't need to pay anything beyond that. See the license details. The ongoing "subscription" is if you want to receive updates (sort of like the system with Ryan's Pro modules), but the reality is that an IDE is a glorified text editor - it's not like they're bringing out must-have new ways to edit text every other month. So you'll be fine with the current version for some years to come.1 point
-
$static_translations['telephone']['default'] = "Τηλ:<br><a href=\"tel:2821011111\">2821011111</a>"; $static_translations['telephone']['english'] = "Phone:<br><a href=\"tel:+302821011111\">00302821011111</a>"; OR $static_translations['telephone']['default'] = "Τηλ:<br><a href='tel:2821011111'>2821011111</a>"; $static_translations['telephone']['english'] = "Phone:<br><a href='tel:+302821011111'>00302821011111</a>";1 point
-
Use the EAP version (early access program): https://confluence.jetbrains.com/plugins/servlet/mobile#content/view/51185764 But you will see soon how helpful it is compared to other IDEs so chances are you will buy it. I also prefer freewares where possible but in this case it's worth the money. I tried Netbeans several times, lately about half a year ago but switched back to PhpStorm.1 point
-
1 point
-
I've tried various modules and import formats (CSV, XML etc) and settled on a custom function using the API and XML format. I found the CSV format limiting as it can not handle data that uses "," and more complex data types. Some of the modules like the importer module also has limitations like not being able to handle Repeater fields etc. I use something called SimpleXML to import the xml file and then use the PW API to create pages. I've included a code snippet below to illustrate. Note the category field below is a PageArray field, so I'm creating a PageArray first and populate it, then assign that PageArrray to the category field. public function Execute() { $import = true; $xmlFile = $this->file; if ($import) { if (!file_exists($xmlFile)) exit($xmlFile . ' failed to open'); $items = simplexml_load_file($xmlFile); foreach ($items as $xml) { //$p = new \Processwire\Page(); $p = new \Page(); $p->of(false); $p->template = wire(templates)->get("id=" . $xml->template); $p->parent = wire("pages")->get("id=" . $xml->parent); $p->title = $xml->title; $p->name = $xml->title; $p->author = $xml->author; $p->content_path = $xml->content_path; ... ... //$p->save(); // try creating PageArray first ???? $cats = new \PageArray(); //$cats = new \Processwire\PageArray(); foreach ($xml->category->id as $id) { $pageid = (string) $id; $cat = wire("pages")->get($pageid); if (!IsNullPage($cat)) $cats->add($cat); } $p->category->import($cats); $p->save(); echo 'new page <a href="' . $p->editUrl . '" target="_blank">' . $p->path . '</a><br>'; } //die(); } }1 point
-
1 point
-
1 point
-
Since i typically maintain separate pages for those types of media (in a media library for every site), it is just a matter of setting up page select field. I use selectize so that the user can see what they are selecting. Also if i use a page for logo, then they can update the logo from the media library without having to change the setting; or they can add several logos to the media library and then select which one to use on the settings page. I don't yet know how to support image/file fields natively in this module, although since the settings pages themselves are pages of template admin, it might be possible. I was actually able to use both image and file fields and upload an image, however there are still errors with the value of the inputfield not yet working... In other news, here are some new screenshots of settings panels using UiKit theme, including a working example of using WireTabs:1 point
-
1 point
-
I'm no Twig expert at all, but I think the foreach loop should look like this: {% set ARTISTS = page.exhibition_artist %} {% for artist in artists %} Maybe it would be easier for you if you do it with plain PHP, without Twig - for me it is1 point
-
there is no dashboard for PW. If you login though, you would see the page tree, that's the admin landing page. I would never permit a client access to changing the site's global base font. As mentioned in posts above this could have not only detrimental effects to the layout of all content elements, but would also be virtually impossible considering that many parts of the base css file (global style for example) may have rules that refer to that loaded web font. If this ability for base font to be selectable in admin was a requirement of the project, then i would neutralize all of the font rules in the css, and place 1 style tag in the header, which would be selected using some settings page (settings factory or custom helper module), this selection would also have the effect of loading the correct webfont (i use webfonts.js for font loading)... so to sum up, yes it is definitely possible to grant control of the global base font for a site to a settings page with the right modules, and code in the header, but whether it would really work is questionable; You also might need to account for 2 fonts, since most sites use 2-3 complementary webfonts each optimized for either headings or body text..1 point
-
Ok, so if I understand it right, you want to force user to pick a template. I'm not sure if this fits your needs but with a bit of JS and hooks you can remove default value and set the template select required (with `required` html attribute), such that you cant get to the next step without deliberately picking a template wire()->addHookAfter('ProcessPageAdd::buildForm', function (HookEvent $e) { /** @var InputfieldForm $form */ $form = $e->return; $form->add([ 'type' => 'markup', 'value' => '<script>document.querySelector("[name=template]").selectedIndex = -1;</script>' ]); $template = $form->getChildByName('template'); if ($template) $template->attr('required', 1); });1 point
-
Just a heads up regarding a possible fix posted in the GitHub issue: https://github.com/processwire/processwire-issues/issues/411#issuecomment-3401392391 point
-
A simple recursive function that walks over all image fields and those inside repeaters(including FieldtypeFieldsetPage) to find images tagged with a certain tag(s). It can easily be extended to file fields by changing instanceof FieldtypeImage to FieldtypeFile, or be restricted to file fields by adding a !$type instanceof FieldtypeFile, too. Adapted from ProcessPageEditLink::getFilesPage() method. /** * Find all images tagged with a certain tag in a page including repeater items. * * @param $page Page to search tagged images * @param $tag string|array Image tag(s). Can be 'foo' for single, 'foo|bar' for multiple OR tags, 'foo,bar' or ['foo', 'bar'] for multiple AND tags * @return array Tagged images in [basename => Pageimage] associated array form or empty an array */ function findTaggedImages(Page $page, $tag) { $tagged = []; foreach ($page->template->fieldgroup as $f) { $type = $f->type; if ($type instanceof FieldtypeImage) { /** @var Pageimages $images */ $images = $page->{$f->name}; if (!$images) continue; $tagged = array_merge($tagged, $images->findTag($tag)->getArray()); } else if ($type instanceof FieldtypeRepeater) { $items = $page->{$f->name}; if (!$items) continue; if ($items instanceof PageArray) { foreach ($page->$f as $item) $tagged = array_merge($tagged, findTaggedImages($item, $tag)); } // FieldtypeFieldsetPage returns a single page instead of a PageArray elseif ($items instanceof Page) { $tagged = array_merge($tagged, findTaggedImages($items, $tag)); } } } return $tagged; } And can be used as $featuredImages = findTaggedImages($page, 'featured'); // get first featured image $featured = reset($featuredImages); // or array_shift($featuredImages)1 point
-
I run all private projects on Bitbucket and open source on GitHub. Never had a problem with either for small and medium sized web projects mainly.1 point
-
We've been running Gitlab CE (self-hosted) for the past 2.6 years. It's been stable so far. If your firm has multiple developers that require access to private repos, hosting a Gitlab CE is cheaper and gives you more control.1 point
-
I use Gitlab since 2014. Gitlab -> great for private repos and organizations Github -> great for open source and tools integration. Github is more known in the open source and many tools (like kanban tools or similar project management type tools) are tailored to Github. The good news is that Gitlab can easily mirror github repos in both directions https://docs.gitlab.com/ee/workflow/repository_mirroring.html1 point