How to place two SilverStripe DefinedUserForms in home page - php

In SilverStripe how do you display two UserDefinedForms on one page?
I can display one UserDefinedForm on a page, but I am unable to display two on the same page. I would like to display two UserDefinedForms on my home page.
To display one UserDefinedForm I put this in my HomePage template:
<div id="contactForm" style="display: none;">
<% control ShowForm %>
<p><strong>$SiteConfig.FormHeading</strong></p>
$Form
<% end_control %>
</div>
Function ShowForm() is in my HomePage.php
function ShowForm() {
$get = DataObject::get_one('UserDefinedForm');
return new UserDefinedForm_Controller($get);
}
My problem is that I have created two forms, one is for contacts and one is for booking test drive. Both forms are UserDefinedForms, so if I write another function in HomePage.php example:
function ShowTestDriveForm(){
$get = DataObject::get_one('UserDefinedForm');
return new UserDefinedForm_Controller($get);
}
it will do nothing, or will render my first contacts form.
If I have created two UserDefinedForms what should the php for test drive form look like?
I tried to get it by URLSegment, but it gives me an internal server error:
public function showTestDriveForm() {
$record = DataObject::get_one("UserDefinedForm", "URLSegment = 'BookTestDrive'");
$results = new UserDefinedForm_Controller($record);
return $results;
}
How do I get the second UserDefinedForm to the homepage template?

You have a general misunderstanding on DataObjects, Pages & Controllers.
UserDefinedForm page type holds a form construction. They are pages, not separate objects (one does not query forms directly). The controller is the part that handles a request and contains an actual form handler.
You have also not specified a version, so I will assume SilverStripe v3.1
The basic thing you're looking for is:
public function ContactForm() {
return ModelAsController::controller_for($this->ContactPage())->Form();
}
public function TestDriveForm() {
return ModelAsController::controller_for($this->TestDrivePage())->Form();
}
Possibly with a bit more error checking.
This code also makes the assumption that your homepage has two has_one relations to UserDefinedForm pages named ContactPage and TestDrivePage.

Related

silverstripe 4 - Render UserDefinedForm on custom page templates

I need some help with converting SS3 to SS4. I would like to render my contact form on another page as well as my default Contact page. I managed to get it working in SS3 but things are a little different in SS4 and I am not sure how to write the function or where to put it. I have tried a bunch of combinations and locations but I need help.
In SS3 I created my UserDefineForm page with its fields. I then added the following to the custom page that I wanted the form to render too:
class IndexPage_Controller extends Page_Controller {
// Sign up form
public function SignupForm(){
$get = DataObject::get_one('SiteTree', "URLSegment = 'contact-me'");
return new UserDefinedForm_Controller($get);
}
}
What/Where do I put the function in SS4 to get the form fields to render on the custom page template as it does on the Contact us page?
Thank you in advance.
The code below should work.
public function getSignupForm()
{
$page = \SilverStripe\UserForms\Model\UserDefinedForm::get()->filter('URLSegment', 'contact-me')->first();
$controller = \SilverStripe\UserForms\Control\UserDefinedFormController::create($page);
return $controller->Form();
}

Silverstripe dynamic page types

Am litle confused with new project. Am working site for one courses school.
Course page:
Courses page is added via administration admin/pages/ and have own page type and data object. Course, CoursePage, CourseCategory. CoursePage has page model and controller where i have few methods for listing courses and categories. Also i have template CoursePage.ss and CoursePage_details.ss.
All courses has one course category.
Inside CoursePage_Controller i have two main methods:
public function details(SS_HTTPRequest $request)
public function ListAllCourses() {
return Course::get();
}
Adding new courses:
Adding new courses is done via admin model. I have CourseAdmin which extends ModelAdmin and all work good.
Displaying courses:
This is done via Course_Controller and Course_Page.ss and Course_Page_details.ss
Everything work fantastic but now problem is comming:
Problem:
My client want to create child pages inside Courses page and assign selected courses on a specific page.
So he want to create new child Web development courses page and want to loop only courses for web development on that page.
Here i have problem becouse am adding courses via admin model. Next, all that sub page must have own page type like WebDevelopmentPage where i will query and filter that courses by category.
So if client want to add new child page and want to assign courses to that child page he must call me becouse i must create new page type and new page template for all that page, for that new child page! That is realy bad...
if there is a way that I could to filter the information through subpages? Or any trick to system automticly create new page type?
Update:
Solution 1:
I try this and work ok, but i think this is a bad practice.
Inside Course data object i add new db field UrlSegment where user must map some url segment like on page url. With what i will filter all on one page
public function Courses()
{
if($this->URLSegment == "all-courses") {
return Courses::get();
}else {
$c = Courses::get()->filter(array(
'UrlSegment' => $this->URLSegment
))->sort('Featured', 'DESC');
return $c;
}
}

Use database data in MVC Master Page

Suppose i'd like to display title of latest articles.
for particular Views , we use controllers to handle that. but for common section of pages like header or footer ,
How to display data(latest articles) from database (within MVC rules) ?
Note: I use php
Please check my approach:
app class:
<?php
class app{
public static function appLoader($app){
include 'apps/'.$app.'/'.$app.'.class.php';
new $app;
}
}
test.class.php :
class test extends app{
function __CONSTRUCT(){
return 'Hello World';
}
}
footer.php:
<footer>
<?php echo app::appLoader("test") // returns 'Hello World' ?>
</footer>
Note: This is w.r.t .Net MVC
If you are following MVC pattern - then there's a concept of "Partial Views" - which is just like user controls, and it can be placed in the main page.
Partial view is also an html page which might just div, no html body head etc because it will be rendered inside main html page
You might need to verify the syntax for Partial Views with PHP. The concept remains same for MVC.
There are various ways to display partial views.
One popular way is the one where Partial view is called by its action method - which will ultimately display the result(the partial view).
The Action method will return a "_Footer" Partial view - where you can put your HTML Code of displaying the data from DB(the latest articles).
The partial view must bind from the list of articles. which is popularly known as Strong Type Binding in .Net - which is nothing but mapping the view(HTML page) to a specific class to display the data from that class.
For your reference the below example can be referred(in .Net):
Create a partial view for footer(_Footer) and call it using Action Method(RenderAction - .Net). This action method can fetch the data from database and display in the partial view(_Footer)
The call to the action method be like from the view(html page):
#{ Html.RenderAction("Index", "Footer", new { Area = "Common", id}); }
And the Controller and action method like:
public class FooterController : Controller
{
public ActionResult Index(int id)
{
var vm = new FooterViewModel
{
Id = id
};
return this.PartialView("_Footer", vm);
}
}

Changing layout of view in Joomla 2.5

I know there are several similar topics around but I read and tried most of them but still can't figure out how to do this.
I have a written a component in Joomla 2.5 and it works so far. I have different views and I can load the views using the controller.php.
One of the views shows a table out of my data base (data about teams).
Now I'd like to have another layout of the same view which would display the data base table as a form so can change the content.
That's the file structure:
views/
- teams/
- - tmpl/
- - - default.php
- - - modify.php
- - view.html.php
That's out of the view.html.php file:
...
// Overwriting JView display method
function display($tpl = null) {
...
$this->setLayout('modify');
echo $this->getLayout();
// Display the view
parent::display($tpl);
}
I tried different combinations of setLayout, $tpl = ..., default_modify.php, etc.
but I always either get the default layout or some error like 'can't find layout modify'
I load the site with .../index.php?option=com_test&task=updateTeams
And the controller.php looks like this:
function updateTeams(){
$model = $this->getModel('teams');
$view = $this->getView('teams','html');
$view->setModel($model);
$view->display();
}
I had a similar problem, I created some kind of user profile view and wanted them to be able to edit the fields without having to create a new model for it (would have similar functions, hate redundancy...). What worked for me is to simply call the layout like this:
index.php?option=com_mycomponent&view=myview&layout=edit ("edit" would be "modify" in your case)
To do this I didn't touch the view.html.php (well I did at first but I didn't have to.). And you don't need to use the controller either. If you want to load the modify view, just add a button to your regular view linking to the modify layout. No need to change anything else.
I happen to have written a blog article about it, check it out if you want: http://violetfortytwo.blogspot.de/2012/11/joomla-25-multiple-views-one-model.html
Hope this helps.
Ok this is the problem .. you don't want another layout, you want a new MVC triad that is based on forms rather than rendering. So if you look at any of the core content components you will see in the backend they have a mvc for say ... contacts and one for contact and contact is the editor. If in the front end you will notice that com_content and com_weblinks have mvc for artice/weblink and then separate ones for editing.
You need a really different model and layout and set of actions for editng than for just rendering.
Old topic, but it might still help.
It seems that when one wants to change the layout, the $tpl must not be included in the display() or must be null.
So the previous code would be:
function display($tpl = null) {
/* ... */
$this->setLayout('modify');
// Display the view without the $tpl (or be sure it is null)
parent::display();
}

Laravel template not looping through array of views

Hoping this is some kind of silly oversight on my part, but I've had little luck finding information about this or other examples of similar usages of Laravel. I'm developing a Laravel 4 site whose content is populated not with a local database, but with posts from a specific Tumblr blog, via the Tumblr API.
Every Tumblr post has a certain type associated with it ("text", "video", "photo", etc.), and each type has entirely different types of content that need to be spit out, so I have a Blade template for each post type, inheriting from a master post Blade template. (Everything is just a stub right now.)
To fill out the front page, in my controller I'm populating an array with those post views ($postViews). What is maddening is that if I loop through $postViews and echo out each individual view in the controller, it contains the proper content--all three views in the array show up on the final site inside their correct templates.
But when I send $postViews off to my welcome view, and then loop through $postViews inside THERE, it renders three instances of ONLY the first view of the array. I have no idea why.
Here's the relevant code. As you can see in the welcome template, I tried looping through $postViews in the welcome view both with native PHP and with the Laravel template syntax. They both exhibit the same behavior: showing only the first of the three posts, three times.
// controllers/HomeController.php
class HomeController extends BaseController {
public function showIndex()
{
$client = new Tumblr\API\Client(CONSUMERKEY, CONSUMERSECRET);
$tumblrData = (array) ($client->getBlogPosts(BLOGNAME));
$postViews = array();
foreach ($tumblrData['posts'] as $post) {
$post = (array) $post;
$type = TumblrParse::getPostType($post);
$postViews[] = View::make('tumblr.'.$type, array('post' => $post));
}
foreach ($postViews as $p){
echo $p;
// This works! It displays each post view properly before
// before rendering the welcome view, but I need them to
// be inside the welcome view in a specific place.
}
return View::make('home.welcome')->with('postViews', $postViews);
}
// views/home/welcome.blade.php
#extends('layouts.master')
#section('title')
#parent :: Welcome
#stop
#section('content')
<h1>Hello World!</h1>
<?php
foreach($postViews as $p) {
echo $p; // Just outputs the first of the array three times
}
?>
#foreach($postViews as $p)
{{ $p }} // Just outputs the first of the array three times
#endforeach
#stop
// views/layouts/post.blade.php
<div class="post">
#yield('postcontent')
</div>
// views/tumblr/photo.blade.php
// Other post types have their own views: video.blade.php, text.blade.php, etc.
#extends('layouts.post')
#section('postcontent')
<h1>This is a photo post!</h1>
<?php var_dump($post); ?>
#stop
I really appreciate any help! I'm new to Laravel, which I'm sure is obvious. And for all I know, I'm doing something wrong in PHP generally rather than in Laravel specifically.
In this instance it probably makes sense to render each view as a string before appending it to the $postViews array using the view render method.
$postViews[] = View::make('tumblr.'.$type, array('post' => $post))->render();
What about nesting views. Check documentation.

Categories