Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/28/2020 in all areas

  1. I hope everyone here is doing well, staying in, and staying healthy. Our town here is under a “stay at home” order, and it’s now the law that you can’t get within 6 feet of any other person when out walking. So haven’t left the house (other than for walks and bike rides) in about 2 weeks now. Though with the whole family home all the time, it admittedly feels a lot busier than before this Coronavirus stuff, I think because there’s now a lot more people to attend to during the day (especially kids). Not much silence compared to before. ? Not a bad thing, just very different. If we’ve got to spend a few months, or even a year this way, it’ll be alright, so long as the internet keeps working. I’m just thankful to have a job where I’m already used to working this way, as I know many of you do too. It seems that this whole situation is going to move a lot of activity online that previously wasn’t, so I anticipate it’s going to be potentially a very busy and important year for web development. Online communication and content delivery is going to be that much more important for the world, making reliability, scalability and security every bit as important. These are always our focus, but just want to emphasize this even more as we look forward. With a world in temporary disarray, you can count on ProcessWire to be an especially stable and reliable tool that gets even better every week, and our community always a friendly and helpful place. I’ve got several things in progress in the core, but nothing far enough along to write about just yet. I’ve also been putting a lot of work into ProCache this week, which is long due for a version update. The module still has quite a bit of PW 2.x architecture that I don’t think is needed anymore, so I’m refactoring and improving quite a bit, in addition to feature updates. Thanks for reading and I hope that you have a good and safe weekend!
    19 points
  2. Ugh... that was really ugly ? Here's a better version: In your autoload module: $this->addHookProperty("User::isCustomer", function(HookEvent $event) { $event->return = $this->user->isSuperuser(); if($this->user->hasRole('manager')) $event->return = true; if($this->user->hasRole('customer')) $event->return = true; }); $this->addHookProperty("User::isManager", function(HookEvent $event) { $event->return = $this->user->isSuperuser(); if($this->user->hasRole('manager')) $event->return = true; }); In your processModule: public function checkAccess() { // if user is neither customer nor manager we redirect if(!$this->user->isCustomer AND !$this->user->isManager) { $this->session->redirect('/your/admin/url/to/no-access-page'); return; } } public function executeDNS { $this->checkAccess(); $user = $this->wire('user'); $out = "<div>Hello $user, here are your dns settings...</div>"; if($user->isManager) $out .= "<div>You are a Manager, so you can edit all settings!</div>"; ... return $out; } A lot better. Welcome to PW greatness ?
    2 points
  3. If one's goal is to get an up or down from an API call, then zero vs. non-zero is functionally and effectively the same thing as boolean. If there's an opportunity to make a method more useful by taking advantage of that fact, then I'll always do it. So yes, you'll find many examples of this in PW. That's always the strategy I've tried to embrace in the PW API and plan to continue going forward. To reiterate what I stated above, the primary purpose of the has() method is not to get an ID—it is instead to check if the system has a page matching the criteria or not, without actually loading the page. Whether the method returns 0 or false makes no difference in telling the caller that the system has no page matching the criteria. Likewise if the page does match the criteria (true vs 1+). Now if you are specifically looking for a getID() function, then yes of course the name "getID" is preferable. I'm happy to add getID() as an alias for times when one might be specifically looking for that particular need. But that's not what I was looking for here. And if anyone else's experience is similar to mine, we will more often be looking to see if the system has any page matching some criteria (whether we want the ID or not). Basically replacing instances where we might have used count() before, with a more efficient alternative. So I feel pretty strongly that the has method name and return value are optimal and consistent here.
    2 points
  4. Hi all, I'm searching for Alpha/Beta tester of the new rewritten Croppable Image module. I opened a new repo on Github, with the name CroppableImage4: https://github.com/horst-n/CroppableImage4 It is a rewrite of the CAI3. I dropped all internal image manipulations, to be more future safe. Now I delegate all this to the parent core image fields methods. To be able to do this, I need to change some things and the module is no longer backwards compatible. A) For the alpha & beta testing, there is a new crop method name: $image->getCrop4(), this may be changed later to the legacy $image->getCrop() method. But for the testing period to avoid conflicts with CAI3, it is named getCrop4(). <- OBSOLETE, see the next post here in thread B) With the first param, you pass the cropname into the method. Optionally you can pass image processing options as a second param, like with the core image field. To do this, you may use an array or a selector string. C) You can use every known options param. Width, Height, Size is ignored! If you also want create WebPs in one go, please add "webpAdd" => true to the options array, (or webpAdd=1 to the options selector string)! D) The resulting image variation names will differ from those of the previous version 3! Please refer to the readme of the repo and, maybe compare it against the version 3, if you not already know it. Thats it so far. I have tested it a bit in the last days and haven't found any issues. But it would be nice if some of you can test it too.
    1 point
  5. Hello, I've run into a case where I don't want a user to be able to edit a parent page, but do want them to be able to sort/move its children. I know that the page-sort permission depends upon the same role having page-edit permissions on the parent, but I wandered if there was a way around this? For now I hide the "Edit" button with CSS if the user is not a superuser, but this is not an ideal solution as they could still potentially edit that page via the correct url. Is there anything I could hook into if a certain user tried to load the edit page for that particular parent template? Something like this, but I don't know how to actually prevent the page loading: $config->addHookAfter('Page::loaded', function (HookEvent $event) { $page = $event->object; if ($page->template == 'projects' && $user->id !== 41) { // Do something to stop that page being edited } }); Thank you for any help
    1 point
  6. I'm old enough to actually remember Macromedia Adobe Flash... sometimes you were forced to use that plugin just to display a (dynamic) custom font (sIFR). Oh the fun we had... sometimes I think the young generation of web developers don't know how lucky they are. ? </derail>
    1 point
  7. $this->addHookAfter('ProcessPageAdd::buildForm', function ($event) { $form = $event->return; // If adding page under particular parent if ($this->input->parent_id === '1041') { // Add inputfield to form after existing title field // If you name the inputfield the same as the field you want to populate // then the entered value will be saved automatically $f = $this->modules->InputfieldText; $f->name = 'myfieldname'; $f->label = 'My Field Label'; $f->description = 'my field description'; $f->required = true; $f->attr('required', 1); // use HTML required attribute too $title_field = $form->getChildByName('title'); $title_field->label = 'Page Title'; $title_field->description = "page title description"; $form->insertAfter($f, $title_field); $event->return = $form; } }); I got this code a long time ago from somebody in this forum, and it works nicely. I can't find the original thread right now. It basically renders the field "myfieldname" in the first screen when you create a new page under parent id 1041. Not sure if that helps for your scenario.
    1 point
  8. This works for me: // To test, add this to your sites/ready.php wire()->addHookAfter('Pages::saveReady', 'checkiconUnique'); function checkiconUnique(HookEvent $event) { $page = $event->arguments(0); $field = $page->getField('icon'); $icon = $page->icon; // preset icon // before the page is saved for the first time it does not have an id if(!$page->id) { $page->icon = "Preset icon " . uniqid(); } else { if(!$page->isChanged('icon')) return; $exists = wire('pages')->get("id!=$page,icon=$icon"); if($exists->id) { // value is not unique! $error = __('icon must be unique'); $exception = sprintf( __('icon [%s] is already in use'), $icon ); $inputfield = $page->getInputfield($field); $inputfield->error($error); throw new WireException($exception); // Prevent saving of non-unique value! } } } Not sure if that works in all circumstances - that's why we build modules for such things. And not sure if a module by Ryan is really a 3rd party module that one should not include in his module ? But maybe it helps nonetheless... I tested it with an "icon" field. You can simple find&replace that string to your fieldname. I made all occurrences lowercase to make that easier.
    1 point
  9. Hi @Gadgetto the screencast was meant to show that I did search for the "unique" feature in the blog but didn't find relevant results ? It was not meant as something useful for your problem. To your problem... Such things are a little hard when one is not directly in the code! Could you please setup two example hooks for the BASIC-PAGE template and the TITLE field. Almost everybody has those available for testing so we could just copy&paste your hooks into site/ready.php and provide tested solutions. One thing that I saw in your code that could be slightly improved: // your version: if ($snipwire->isProductTemplate($page->template)) { ... // better: if($page->isSnipProduct) { ... $wire->addHookProperty("Page::isSnipProduct", function($event) { $snipwire = ... $event->return = $snipwire->isProductTemplate($event->object->template); } That's just a little detail but IMHO overall that makes code more readable... Another option would be to use the new Page Classes, but I guess that's no option for you because you because of the version requirement ?
    1 point
  10. @Gadgetto Have you seen this? https://github.com/processwire/processwire/blob/dev/wire/core/FieldsTableTools.php#L108
    1 point
  11. Hi, @AswinC and welcome to the forum! Sounds like a fun project ? I'd suggest something like this Permissions: dns-view dns-edit licensing-view licensing-edit Roles: customer (dns-view, licensing-view) manager (dns-edit, licensing-edit) Then you build ProcessModules for those management interfaces and simply check for the role: public function checkAccess() { // $su is true for superuser $su = $this->user->isSuperuser(); // set user info object // for superusers all properties will be true $u = (object)[ 'isCustomer' => $su ?: $this->user->hasRole('customer'), 'isManager' => $su ?: $this->user->hasRole('manager'), ]; // if user is neither customer nor manager we redirect if(!$u->isCustomer AND !$u->isManager) { $this->session->redirect('/your/admin/url/to/no-access-page'); return; } // user has access, return info object return $u; } public function executeDNS { $u = $this->checkAccess(); $user = $this->wire('user'); $out = "<div>Hello $user, here are your dns settings...</div>"; if($u->isManager) $out .= "<div>You are a Manager, so you can edit all settings!</div>"; ... return $out; } That was really quickly typed here in the browser. Maybe even more elegant would be to add $user->isCustomer and $user->isManager to your user object in an autoload module, then you'd have it available in all your API ? See You can then also prevent editing of pages via simple hooks that check if the user is a customer or manager. Then you can simply build your own logic like customers can only edit their own dns pages etc.; I'd really do that using ProcessModules and not via the page tree. The page tree has big problems hiding/showing stuff based on access related things (see AdminRestrictBranch and its limitations).
    1 point
  12. Super Tracy!! LOL .. Another feature discovered today:
    1 point
  13. So I just opened an issue and closed it immediately because I realized that my proposed solution already exists in the form of wirePopulateStringTags ? It works perfectly for my use case, only requiring to use {title} with curly braces instead of title for the first example, which in a way is even more predictable. Those functions should really have better visibility in the documentation ?
    1 point
  14. Hi all, Apologies for the very loud silence! I hope to elaborate more on this a bit later. However, rather than keep people guessing, I'll write something short. I have been working my fingers to the bone to release a beta by spring 2020. I suppose it hasn't gone unnoticed that I rarely post in the forums at large these days. This is because I am dedicating nearly all my time to Padloper. The plan was to start early beta testing in mid-April 2020. This was largely on track. Like many of us, maybe most of us in the forums, we have all been affected in one way or another by the current situation in the world. This has thrown a monkey wrench in the works. I have had to readjust how I work, albeit my productivity taking a hit. I wish I could properly 'guesstimate' how much delay this is going to cause but it will just be futile. On the other hand, I appreciate that you have been waiting for a relatively long time for this release. I want to reassure you that I am not just kicking the can down the road. Maybe I should have been showing you more screenshots of progress but currently, that would just eat further into my limited time. Thanks for reading, and hopefully, your patience. Cheers.
    1 point
  15. I suggest setting the maxFiles setting of the inputfield dynamically with a hook. There are many different methods you could potentially hook - I don't know if you're talking about Page Edit, ProcessProfile, ProcessUser, or some form on the front-end, and I don't know if by "group" you mean "role". But here is something that you can adapt to suit: $wire->addHookBefore("InputfieldImage::render", function(HookEvent $event) { /* @var InputfieldImage $inputfield */ $inputfield = $event->object; $field = $inputfield->hasField; if(!$field || $field->name !== 'images') return; $user = $event->wire('user'); if($user->hasRole('foo')) { $inputfield->maxFiles = 1; $inputfield->description = 'You may upload a maximum of 1 image.'; } elseif($user->hasRole('bar')) { $inputfield->maxFiles = 2; $inputfield->description = 'You may upload a maximum of 2 images.'; } else { $inputfield->maxFiles = 0; // No limit } });
    1 point
  16. @bernhard Im well aware of profiler-pro ? I am a ProcessWire fanboy since 2014 but unfortunatly lost my forums account ? maybe some old veterans remember me. Anyways, why do I replicate the pro module you may ask, good question. I have a lot of small PW Instances running for various reasons and dont see the need to purchase a module for my profiling needs. Usually my instances are running solely on the ProcessWire Admin because the time I did websites are long gone. This in mind there are times I want to see how a specific module I my application runs. How do I achieve this? The core class ProcessController exposes the hookable Method ::execute. If your site is in Debug=true you already get timers before and after the method call which is totally fine, but once in production I want to avoid setting the site into debug mode just to get these timings. So we add 2 Hooks to ::execute $this->addHookBefore("ProcessController::execute", $this, 'startProfiler'); $this->addHookAfter("ProcessController::execute", $this, 'startProfiler'); This gives us also the ability to enrich our profiling with some more data like the requests memory_peak_usage or the avg_sys_load for the last minute. These are the 2 values I am the most interested in because they will provide me enough data to see bottlenecks not only on a custom Process Module but also on a specific method. For example this dataset will give me the opportunity to track down a single method in one Class to inspect the code if there is something fishy.
    1 point
  17. v0.3.0 released. Adds support for PageListSelect and PageListSelectMultiple inputfield types. Also adds support for PageAutocomplete inputfield type but only when used via a HannaCodeDialog::buildForm hook. From the module readme: @maddmac, I think you must be referring to PageListSelect which is used in InputfieldSelectorSelectID rather than that module as a whole. In v0.3.0 you can now use PageListSelect with HannaCodeDialog, either by setting a "attributename__type=pagelistselect" attribute in the tag settings or by using a HannaCodeDialog::buildForm hook.
    1 point
  18. Hey, I've made good progress. I think I have solved the issue for updating / changing from CAI3 to CAI4! ? - So, if you want to use a CroppableImage field for a fresh new site, simply go directly with CroppableImage4! (once it is officially released) - And if you have the CroppableImage3 on an existing site, but want to upgrade to CroppableImage4, (because you need WebP support), follow these easy steps: First update CroppableImage3 to the latest version 1.2.0! After that, additionally install CroppableImage4. Now you can use both modules with the same ->getCrop() method call on pageimages. The getCrop hook "knows" from which field and module version it comes. ? Therefore, from now on, you are free to start using CAI4 for new created template calls to CAI4 fields, while the older CAI3 calls can stay in and are fully functional without any changes. If you want to switch CAI3 fields to CAI4 fields, to benefit from the new functionalities, you can do that in the admin > setup > fields > YOURFIELDNAME editor, by changing the (field) type. (see screenshot beneath, & yes, KEEP SETTINGS!) The only thing you have to check, before doing that, is: looking into your templates code, if you have made use of the optional second param in the old CAI3 ->getCrop() calls. If no, what I think is 99.9% the case, you have to do nothing. If you make use of it, you need to change / adapt your method call in the template file. That's it. Summary: update CAI3 install CAI4 change the fieldtype(s) from CAI3 to CAI4 When I've got some feedback from beta testers (and everything works out as expected) I will release the CAI4 through the modules directory. Until then, you get the RC2 version of it on GitHub: https://github.com/horst-n/CroppableImage4
    1 point
  19. It seems that the user needs to have the page-edit permission for both the parent page and the child page in order to sort the child page. I hadn't noticed this before. It's a shame that the page-sort permission can't be granted independently of page-edit as it seems like they involve quite different levels of risk/responsibility. I opened a request at GitHub: https://github.com/processwire/processwire-requests/issues/290 As for a hook you could use this in/site/ready.php: // Just for your target role if($user->hasRole('editor')) { $wire->addHookAfter('ProcessPageEdit::execute', function(HookEvent $event) { /* @var ProcessPageEdit $ppe */ $ppe = $event->object; $page = $ppe->getPage(); // The names of templates that the user is not allowed to edit $disallowed_templates = ['colours', 'colour']; if(in_array($page->template->name, $disallowed_templates)) { // Replace the Page Edit markup $event->return = 'You do not have permission to edit this page.'; } }); } This may not be 100% secure in that a person could theoretically create their own edit form in their browser dev tools (although I think that's a very unlikely possibility). But if you wanted to be extra safe you could follow an alternative approach of limiting access at the field level for all the fields in the relevant templates. Depending on the number of fields that could be a hassle via the admin interface so you could look into doing it via the API.
    1 point
  20. I'm working in version 3 and can't remove the settings tab using your example. Maybe something new has changed? But $config->advanced = true; works perfectly and is a better solution as it's already per-template.
    1 point
  21. Woohoo! Thanks. $config->advanced = true; does the trick!
    1 point
  22. Hi @ethfun - welcome to PW! We do have default values now for certain fields. I don't recall all of them, but definitely for Integer, which should work if you are looking for a span value like in Joss' post. Of course if you need another fieldtype, you can always just do this in your template code: $value = $page->fieldname ?: 4
    1 point
  23. Hey! New to ProcessWire but I am *loving* its flexibility and extensibility! Thanks for all the work on it. I just wanted to swing by this discussion and see if there was any chance that default values had been reconsidered? I'm looking for a way to do exactly what @Joss stated above.
    1 point
  24. 1,5 month later, after I did most of the project and be sure that I understand PW system, I finally finished that part. It's not perfect of course but it's working fine. Here is how I did it: Templates And Fields: I created 2 templates: grid and grid_item and 1 pagetableextended field grid_items. In grids page I can enter grid_items like below: Title, summary, featured_image for content on the grid items, external url for obvious reasons, grid_ratio is to determine size of item. Design is limited with ratios from 1x1 to 3x3, so I made it selectable page items from options use_border : for images with white bg, so they don't look like they are floating Modules I have created 3 modules. InputfieldGridBuilder,FieldtypeGridBuilder and GridBuilder. Whenever I save the page, new items from grid_items pagetable are available to use like below. I can order items, add new rows, delete row etc. Whenever I change something, there is a method that works to serialize data to the hidden input field,InputfieldGridBuilder. Also, just in case I call the function it every 5 seconds. I make a small fixed grid that is very similar to the one used in the frontend. So anything that you can do here with jQueryui sortables, it's available for using in the frontend. Last module GridBuilder is used for mostly utility purposes for both frontend and backend. It has methods like getItemSize, getItemImage, build etc. Frontend Normally these will be used in homepage but I made the view of page available to users with editing roles, so before using them they can see that it look like. For example this one in the gif above looks like this. So even with the empty rows, it works. And for using in the homepage, I added a multiple selection page field. So they can use more than one grid, or with the location options we already added they can select to have a different view for different countries. (I added Location settings is globally for every page) Questions, critics, feedbacks or "hi,there buddy"'s are highly welcomed.
    1 point
  25. Not sure why this hasn't been mentioned, so I am wondering if I am missing something relevant, but why not use the $template->noSettings option? Do you need to hide on a page basis, rather than per template? Anyway, if it suits your needs, turn on advanced mode in your config.php file and then you will have a Disable Settings Tab? option on the Template's System Tab. Hope that might help.
    1 point
  26. Check out this helper module from Soma: https://processwire.com/talk/topic/3159-hide-settings-tab-in-page-edition/?p=31126
    1 point
  27. No need to remove it from the template, just make it hidden and not required in the context of that template. I don't think there is really any need to populate it all in this case, but it would be possible via a hook if you really want to. You could also remove the global flag for title so it is not in the template at all, but I think the former approach is better.
    1 point
  28. 1) a) I think the best approach is to store all the content pages under one hidden parent using the Details > Select a Parent for Items b) Not really an issue if you do a) c) Make use of Input > Automatic Page Name Format, and then go to the template context settings for the title field and make it invisible and not required. 2) This can be handled by setting the allowed parents for these content block templates. Hope that helps.
    1 point
  29. Antti has been developing a Shop module for ProcessWire and it is in successful use already. I'm not sure how many other users might be using it, but I think he's done a very nice job with this. However we don't have plans for e-commerce to be part of ProcessWire's core product, at least not in the current roadmap. So any e-commerce solutions for ProcessWire will be 3rd party solutions, whether running on ProcessWire or on an external service. I've developed and run an online store for many years and have quite a bit of experience with several self-hosted e-commerce software products, and more recently, hosted e-commerce products. When a client asks me what to do for e-commerce, I like to point them towards services like Shopify (my favorite), Volusion, BigCommerce, etc. These services are targeted specifically towards the needs of e-commerce in a way that no self hosted product can touch (at least for what matters to me and my clients). Plus they are hookable (at least Shopify is) making it easy to perform actions in your PW site based on an order, in real time. Paid membership sites suddenly become a piece of cake. This makes nearly anything possible, and IMO more powerful even than dedicated products like Magento. Now with PCI compliance (at least in the US) I really dislike the hassle and time expense of self hosted solutions for my own needs. I don't think ProcessWire needs to be all things to all people, and I'd rather focus our energy on the things where we are and can be better than everyone else. For the same reason, I don't want us to invest time in creating forum software when something like IP.Board exists. We want to empower web developers with the best solutions out there. This is a much bigger question for proprietary and non-open source products. It's a good question, but doesn't have the same gravity when applied towards an open source product with hundreds (or thousands) of people around the world familiar with the system and code. At least in our case, when a bug turns up, many times the user submits a fix with the bug. Beyond these forums, I also do some support email. But very little comes to me anymore. The forums and community here have been better than I could have ever imagined. I should also note that a goal for 2013 is to provide commercial support options for those that want it. I'm not yet certain if the market is there for it, but it's something I would like to have available. We are on a path for growth and I see us continuing our current strategy of building and improving the software and resources around it. My 5-year goal has been for us to power 3% of the PHP open source CMS-driven sites in the world and/or be top 10 (open source) in terms of usage. I think that our growth comes from WordPress users looking for more, and front-end developers getting into content management without a previous allegiance. We'll also get our users from other CMSs. But WordPress is the one building the audience, and the developer and non-blog-portion of that audience is using the wrong software. With that audience, ProcessWire answers everything that WordPress can't, while being simpler to use and develop for. There are other CMSs that are also good stepping stones, but all are significantly more complex.
    1 point
  30. Hi I know this is an old topic, but I was just searching for this. A default value for me is, as someone mentioned above, a pre-filled value that will be used if you don't replace it with anything. For instance, I have a field that asks for a "span" value for a box. If it is not filled in, I want it to default to 4. Now, I can easily achieve this in the template, but the problem is that the user cannot see that it defaults to 4 - so having the field pre-filled not only gives me a starting value, but also informs the user. Joss
    1 point
  31. I've always thought that the "template engines make it easy for non-programmers" was a myth, as it really just comes down to semantics and what characters you think are easier to type. But the reality is that template engines give you something like a jailed environment, and that increases the comfort level of some people. The prospect of limitation becomes an asset in that context. It means it's going to be harder to break things, and there is going to be a ceiling on what can be learned. I don't ever want to be in a "jailed" environment with a low ceiling, but also kind of understand the appeal to someone that may have never stepped beyond the likes of EE (which has come crossover with our audience). As we work to broaden the audience for ProcessWire, an alternate template engine for those that desire limitation here may help us to capture new audiences. There is also just the word "PHP", which scares off some, regardless of what is real or what we do. ProcessWire is always going to be an PHP API-driven environment at it's core, but I'm not opposed to adding on template engine(s) as an option for those that want them, in the future. It's something that's not at the top of the list on priorities, but it is something we'd like to eventually offer. They are a little more tricky to implement in PW vs. a system that is built purely for tags. The reason for this is that ProcessWire templates are executed directly by PHP rather than by ProcessWire itself. ProcessWire just hands off some API variables to the templates and lets PHP and the template execute natively. It's nice, fast and efficient. (Other systems like EE actually execute PHP code in templates using eval(); which is slow and inefficient… they hope you won't be using much PHP). The way we'd have to implement a template engine in ProcessWire, while still retaining the speed, is with compiled templates. The template using template-tags would have to be compiled to a native PHP template before it could be executed. Lots of these new template engines are designed to work that way anyway, so not a big deal, but just outlining how it would be done.
    1 point
  32. Not evangelical at all, as I'm not even an experienced programmer. I only learned PHP in the past few months, and I can say it was mostly because of the way PW is thought out. As a Designer I never thought I would be writing some rather advanced PHP so soon, but because PW uses PHP instead of a templating engine, and because it's designed to make it so easy for anyone to achieve basic tasks, you just feel encouraged to go further and further without any constraints. Really, just start building a website with PW without thinking of external tools, you don't even need to install any of the excellent custom modules that are already available, and you will see how easy it is and how powerful it can get
    1 point
  33. you can use Markdown or Textile: http://processwire.c...text-formatter/ or, if the only thing you want is the <br> where there is a new line; you can use "nl2br" on a regular text area: http://php.net/manua...ction.nl2br.php <?php echo nl2br($page->field); ?>
    1 point
×
×
  • Create New...