I am having a hard time figuring out how the exactly the routing works in JomSocial. Does anyone know how to create a new view?
First of all, you create a controller to make a request of a view:
file: controllers/hello.php
<?php
// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die();
class CommunityHelloController extends CommunityBaseController
{
function helloWorld() //index.php?option=com_community&view=hello&task=helloWorld
{
$document = JFactory::getDocument();
$viewType = $document->getType();
$view = $this->getView('hello', '' , $viewType);
echo $view->get('helloWorld');
}
function hello() //index.php?option=com_community&view=hello&task=hello
{
$document = JFactory::getDocument();
$viewType = $document->getType();
$view = $this->getView('hello', '' , $viewType);
echo $view->get('helloWorld');
}
}
?>
View: views/hello/view.html.php
Here you place variables that will be passed to template file
For example:
<?php
defined('_JEXEC') or die('Restricted access');
jimport ( 'joomla.application.component.view' );
class CommunityViewHello extends CommunityView {
function helloWorld() //This function shows a "Hello World" without an template view
{
echo 'Hello World';
}
function hello()
{
$user = CFactory::getUser($userid);
$tmpl = new CTemplate( ); //Call a template file
echo $tmpl->set ( 'user', $user )
->fetch ( 'hello' ); // Returns the templates/default/hello.php file
}
}
File templates/default/hello.php:
<?php defined('_JEXEC') or die();?>
<h2> This is an example </h2>
<div class="container">
<p> Hello, <?php echo $user->name; ?></p>
</div>
That's all!
I may have made this as a comment to the answer given by #Thavia-Farias in 2013, but my reputation is not high enough to comment. The content of my answer will restate her information along with crucial new information, corrections, and enhancements according to my experience using Jomsocial 4.2.1:
First off, the controllers/hello.php as provided by #Thavia-Farias has an error: In both the function helloWorld() and function helloWorld()function hello(), the final line is echo $view->get('helloWorld');, but the function in function hello() should be echo $view->get('hello');. As it stands, both *index.php?option=com_community&view=hello&task=helloworld and index.php?option=com_community&view=hello&task=hello will both call the helloworld view, rather than the second one calling the hello view as it should.
Also, in my experience, rather than putting the template at the path /templates/default/hello.php, I put it at /templates/customtemplatename/html/com_community/layouts if you are using a cusomt template or /components/com_community/templates/jomsocial/layouts/ if you are using the default jomsocial template.
create /components/com_community/controllers/hello.php:
<?php
defined('_JEXEC') or die();
class CommunityHelloController extends CommunityBaseController
{
public function renderView($viewfunc, $var = NULL) {
$my = CFactory::getUser();
$jinput = JFactory::getApplication()->input;
$document = JFactory::getDocument();
$viewType = $document->getType();
$viewName = $jinput->get('view', $this->getName());
$view = $this->getView($viewName, '', $viewType);
echo $view->get($viewfunc, $var);
}
function helloWorld()
{
$this->renderView(__FUNCTION__);
}
function hello()
{
$this->renderView(__FUNCTION__);
}
function display($cacheable = false, $urlparams = false) {
$this->renderView(__FUNCTION__);
}
}
?>
create /var/www/html/components/com_community/views/hello/view.html.php:
<?php
defined('_JEXEC') or die('Restricted access');
jimport ( 'joomla.application.component.view' );
class CommunityViewHello extends CommunityView {
function helloWorld() //This function shows a "Hello World" without an template view
{
echo 'Hello World';
}
function display() //This function what happens when the hello view is called without a task
{
echo 'welcome to the main landing page for the hello view! There is nothing else shown here besides this message.';
}
function hello()
{
echo $tmpl->fetch('hello');
}
}
As you can see, if you want your view to have a default view even when no task is called, similar to what happens with /index.php?option=com_community&view=groups then you will want to name a task as function display in the controller and in the view.
finally, create /components/com_community/templates/jomsocial/layouts/hello.php:
<?php defined('_JEXEC') or die();?>
<h2> This is an example </h2>
<div class="container">
<p> Hello, <?php echo $my->name; ?></p>
</div>
$my was defined way back in the controller! When your views and tasks group big enough, you will have different files for each task. The tasks files are with the fetch function in the view.html.php.
$tmpl = new CTemplate( ); //Call a template file
echo $tmpl->set ( 'vars1', $vars1)
echo $tmpl->set ( 'vars2', $vars2)
echo $tmpl->set ( 'vars3', $vars3)
->fetch ( 'hello' );
calls the /components/com_community/templates/jomsocial/layouts/hello.php file.
Using ->fetch ( 'hello.greeting' ); calls /components/com_community/templates/jomsocial/layouts/hello.greeting.php.
If you want to create a new directory for these then ->fetch ( 'hello/create' ); calls
/components/com_community/templates/jomsocial/layouts/hello/create.php
If you want to create menu items and aliases for your new components, then you need to create a new file (as well as a second and modify a third if you want to do pass menu-item defined parameters to your tasks):
create file: /components/com_community/views/hello/metadata.xml:
<?xml version="1.0" encoding="utf-8"?>
<metadata>
<view title="Groups">
<message>
<![CDATA[
Hello view
]]>
</message>
<options var="task">
<default name="Hello" msg="displays landing page" />
<option value="hello" name="- one greeting" msg="Display detail page of one greeting" />
<option value="helloWorld" name="- helloworldview" msg="Display whatever you have in the hello world task" />
</options>
</view>
<state>
<name>Hello Groups Layout</name>
<description>Hello Groups listings</description>
</state>
</metadata>
This file will add items to the "community" section of the menu in the administrator menu panel. The option values are the names of the tasks. The option without a value that is uses the default tag will pull up the display function described earlier.
If you need to add parameters to the file, then you need to do something a bit complicated:
create /components/com_community/views/hello/tmpl/default.xml:
<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="Name" option="View">
<message>
</message>
</layout>
<fields name="params">
<fieldset
name="basic"
label="Selected Group">
<field
name="item_id"
query="SELECT `id`, `name` FROM #__community_groups_category WHERE ORDER BY `id`"
type="sql"
key_field="id"
value_field="name"
label="Associated Group"
require="true"
description="Select the jomsocial group whose hello task this will be associated with">
</field>
</fieldset>
</fields>
</metadata>
This will create a tab wherein users can specify one group out of available groups in the database. It will assign the id of the group to the parameters field in the #__menu database table in the params colums JSON object as the value for the item_id key. In order for your view to use that value when rendering the page, include the following code in views/hello/view.html.php:
$mainframe = JFactory::getApplication();
$jinput = $mainframe->input;
$document = JFactory::getDocument();
// Get category id from the query string if there are any.
$groupId = $jinput->getInt('group', 0);
// Load the parameters.
$params = $mainframe->getParams();
$params_array = $params->toArray();
if (isset($params_array['item_id']))
{
$groupId = $params_array['item_id'];
}
In this way, your task can receive the necessary specifics from either the URL if given from within your component(option=com_community&view=hello&task=hello&groupid=5), or from being called by a main menu or jomsocial toolbar item drawing of the stored parameters in the menu database table for that menu item.
The options and tab that you create here will be visible for all menu items of this task. If you want different tabs for different menu options, you will have to create entirely different views. having everything in one view may lead to unused and potentially misleading tabs where values can be set by your users but that will not or should not be used by the actual task specified by the user.
Forgive me for not testing every line of this code in an integrated component. I have done all of these functions in my view but have abridged my code which was built with initial guidance from #Thavia-Farias's answer. While it is more clear than posting my extensive code, it has not been tested in it's current form for functionality. Be sure to check your php error logs to debug your project. I have to log in as root (sudo su) and check with nano /var/log/mysqld/error_log on my system. Good luck!
Related
I trying to create a custom settings page for my plugin, but I'm unable to make the page display a custom settings page, to make things simple I just want to display the section header.
Here is what I have.
private function add_hooks() {
add_action('admin_menu', array($this,'register_menu'));
add_action("admin_init", array($this,"display_options"));
}
public function register_menu() {
add_menu_page('Feed','API FEED','manage_options','adt-feed',array($this,'include_admin_page'),'dashicons-format-image');
}
public function include_admin_page() {
return include_once( PLUGIN_PATH 'admin/view/config-page.php' );
}
public function display_options()
{
//section name, display name, callback to print description of section, page to which section is attached.
add_settings_section("adt_general_section", "Header Options", array($this, "display_header_options_content"), "adt-feed");
}
public function display_header_options_content() { //THIS NEVER GETS CALLED
echo "PLUGIN HEADER SECTION";
}
and them in my config-page.php i have:
<div class="wrap">
<div id="icon-options-general" class="icon32"></div>
<h1>ADT Feed Options</h1>
<form method="post" action="options.php">
<?php
//add_settings_section callback is displayed here. For every new section we need to call settings_fields.
settings_fields("adt_general_section");
// Add the submit button to serialize the options
submit_button();
?>
</form>
</div>
Using some "die()" calls i manage to find that display_header_options_content never gets called, if i change "adt-feed" for "general" in the add_settings_section, i can see the message: "PLUGIN HEADER SECTION" in the General settings page.
thanks in advance for any help!
You need to call
do_settings_sections( 'adt-feed' );
in config-page.php.
A good place to put this is just before the call to submit_button();
I have a custom block which has a default view with a form in it. When that form is submitted I set a controller flag and the block is (should be) updated to display more information.
The problem is my view is treating it like I have no data/variables set
Controller.php
public $unlocked = false;
public $employer;
public $shortname = "not loaded";
public function on_page_view() { //already overridden because I'm compiling LESS
...
$this->setViewVariables();
}
function setViewVariables() {
$this->set('shortname', $this->shortname);
$this->set('is_unlocked', $this->unlocked);
...
}
public function action_accesscode_unlock() {
$this->unlocked = true;
$this->shortname = "fred";
//Have also tried calling $this->setViewVariables(); as well,
//before I realised view() and on_page_view() were called after this anyway
}
View.php
<?php if ( !$is_unlocked ) {
echo $shortname; //does correctly display the default value
?>
<form action="<?php echo $this->action('accesscode_unlock')?>" id="accessform" method="post">
...
</form>
<?php } else {
//THIS section is never displayed (always reloads form with default name)
echo $shortname;
} ?>
What am I doing wrong here so that the new variable values are never set in the view?
Edit
After replying to JohnTheFish I just realised, the LESS compilation code I use includes the following lines (used to get block path). Could this be changing the instance used for different parts of the lifecycle?
$bv = new BlockView();
$bv->setController($this);
$bv->setBlockObject($this->getBlockObject());
on_page_view runs before action_accesscode_unlock, so the logic of action_accesscode_unlock does not happen until after the variables are set.
You could try adding a call to setViewVariables to the end of action_accesscode_unlock.
(In answer to your edit, yes, it could)
In Wordpress, my goal is to be able to give a custom class to every widget that I put in the sidebar.
Preferably I would like to add this class in the widget settings of each widget. ALSO 3rd party widgets.
I was thinking of changing the classname, because the classname is already passed to the register_sidebar function (%2$s):
<?php
register_sidebar(array('before_widget' => '<aside id="%1$s" class="widget %2$s blue">'));
?>
Ofcourse I shouldn't change WP core code or 3rd party plugins. This means that I need to write a plugin that will hook into the widget configuration process.
I already found out that it's possible to modify all widgets forms, by hooking into action 'in_widget_form':
<?php
add_action('in_widget_form', 'teaserWidgetAddToForm');
function teaserWidgetAddToForm($widget_instance) {
?>
<label for="<?php echo $widget_instance->get_field_id('teaser-classname'); ?>">Custom classname(s):</label>
<input type="text" id="<?php echo $widget_instance->get_field_id('teaser-classname'); ?>" name="<?php echo $widget_instance->get_field_name('teaser-classname'); ?>">
<?php
}
?>
This data should be saved by the Widget super class, but how do you retrieve this data (so when opening the widget settings later shows what you filled in earlier)
And, this saved data should be put in the widget instance -how is this done? I guess by using something like:
<?php
$wp_registered_widgets[<widget_id>]['callback'][0]['widget_options']['classname'] = <chosen_class>;
?>
So basically I have 2 questions:
Am I using the proper way to address this problem (styling of individual widgets)
If so, how can I modify a widget instance to save and retrieve additional settings, without having to modify Wordpress or 3rd party Plugin source code.
By default each widget instance has a unique ID which can be used to style it.
In order to save data from fields added in an in_widget_form action, you need to also have a widget_update_callback filter.
function my_widget_update_callback($instance, $new_instance) {
$instance['my_classnames'] = $new_instance['my_classnames'];
return $instance;
}
To display the saved value in the form you'll need to first retrieve the instance settings.
function my_in_widget_form($instance) {
$settings = $instance->get_settings();
…
Finally, I think the simplest way to add your custom classes is in a widget_display_callback filter, which runs before a widget is displayed. You have to display the widget yourself because you can only return an instance from this filter, and instances do not control the widget CSS classes.
function my_widget_display_callback($instance, $widget, $args) {
if (!isset($instance['my_classnames'])) {
return $instance;
}
$widget_classname = $widget->widget_options['classname'];
$my_classnames = $instance['my_classnames'];
$args['before_widget'] = str_replace($widget_classname, "{$widget_classname} {$my_classnames}", $args['before_widget']);
$widget->widget($args, $instance);
return false;
}
See this article for more info on the available hooks related to widgets: http://shibashake.com/wordpress-theme/wordpress-widget-system
I've a module (named Brèves) and in the index I need to be showed to columns: the first one shows only entries with an image; the second one shows entries without image. the thing is that I only want to be show the last 4 entries in each column. How can I do it? thank you
Symfony is a web application framework written in PHP which follows the model-view-controller (MVC) paradigm.
Your controller:
In your action:
// Action (controller) - apps/frontend/modules/youmudule/actions/actions.class.php
public function executeName(sfWebRequest $request)
{
$this->entries = Doctrine_Core::getTable('YouTableName') ->getEntry();
}
Your model:
Plase where you put all your "query"
// Model - lib/model/doctrine/YourtablenameTable.class.php
public function getEntry()
{
$q = $this->createQuery('a')
->addORDERBY ('created_at DESC')
->limit(4);
return $q->execute();
}
Your view:
// apps/frontend/modules/youmudule/templates/nameSuccess.php
<?php foreach ($entries as $entry): ?>
$entry->getSomeData()
<?php endforeach; ?>
Read this tutorial
Is there a plugin or something that creates PDF files from a entered by the user form data, when it clicks on the submit button?
if youre wanting a form filled in, then the details of that form processed and sent to you via email with a pdf attachment of the details, i had something similar a few weeks back, I couldnt find anything that would work the way i wanted, so....
I setup my form then using a custom page template I assigned that to a page, then using php and the html2pdf class i created my pdf which was emailed as an attachment...
heres the code i used..
been minified for this page (remember to sanitize your user input).
<?php
/*
Template Name: FORMTOPDF
*/
?>
<?php get_header(); ?>
<style>
/* STYLES FOR ERROR PLACEMENT */
label {
width: 80px;
text-align: right;
float: left;
}
.formerror {
border: 1px solid red;
background-color : #FFCCCC;
width: auto;
padding: 5px 0;
padding-left:10px;
}
.errortext {
font: bold smaller sans-serif;
}
</style>
<?php
// CREATE AN ARRAY FOR OUR ERRORS
$arrErrors = array();
// Check for FORM SUBMISSION
// using hidden form field
if(isset($_POST['action']) && ($_POST['action']=='send'))
{
/* ================= START FORM DATA ========================= */
$name = trim($_POST['name']);
if ($name=='') $arrErrors['name'] = 'Please provide your name.';
$email = trim($_POST['email']);
if ($email=='') $arrErrors['Email'] = 'Please provide your Email Address.';
$comments = trim($_POST['your-comments']);
if ($comments=='') $arrErrors['Comments'] = 'Please add your Comments.';
/* ================= END FORM DATA ========================= */
if (count($arrErrors) == 0) {
// Process form here
/* ================= START PDF CREATION ========================= */
$strContent = "<p>Submission from ".$name."</p>";
$strContent.= "<p><strong>Name</strong>:".$name."</p>";
$strContent.= "<p><strong>Email </strong>: ".$email."</p>";
$strContent.= "<p><strong>Comments</strong> : <br />".$comments."</p>";
/* ================= END PDF CREATION ========================= */
// Include our HTML to PDF creator
// FROM THEME DIRECTORY?
require(TEMPLATEPATH.'/html2pdf/html2fpdf.php');
$pdf=new HTML2FPDF();
$pdf->AddPage();
// folder location of HTML file
$fileLocation = "wp-content/uploads/";
// Call to the file name from the URL
$fileName = "Form_Submission_From_".$name;
// add the location 'wp-content/uploads/' to the fileToOpen
$fileToOpen = $fileLocation;
// Then add the actual file name // form_submission.pdf
// output should look like 'wp-content/uploads/form_submission_from_(name).pdf'
$fileToOpen .= $fileName.".pdf";
// Open the file with read access
$fp = fopen($fileToOpen,"r");
//$strContent = fread($fp, filesize($fileToOpen));
// Close of the page
fclose($fp);
// Create new PDF document from the Content
$pdf->WriteHTML($strContent);
// create our PDF in the wp uploads folder
$pdf->Output("wp-content/uploads/" .$fileName. ".pdf");
/* ================= END PDF ========================= */
/* ================= START EMAIL ========================= */
$headers= "From: YourWebsite <info#yourwebsite.co.uk>\r\n\\";
$emailSubject = "Submission from " . $name;
$emailAdmin = "admin#yourwebsite.co.uk";
$emailMessage = "Submission from ".$yourcompanyname."\n\n";
$emailMessage.= "Company Name: ".$yourcompanyname."\n";
$emailMessage.= "Email : ".$email."\n";
$emailMessage.= "Comments : \n".$comments."\n\n";
$attachments = array(WP_CONTENT_DIR ."/uploads/".$fileName.".pdf", $target_path);
wp_mail($emailAdmin, $emailSubject, $emailMessage, $headers, $attachments);
// Delete our PDF from the server after email Sent
// uncomment this to delete after email sent?
//unlink($fileToOpen);
/* ================= END EMAIL ========================= */
// show thank you message if successful
$strGood = '<div class="formerror" style="background:#FFC;">
<h2>Thank You</h2>
<p>Thank you for contacting us.</p>
</div>';
}else{
// The error array had something in it. There was an error.
// Start adding error text to an error string.
$strError = '<div class="formerror"><p><img style="margin-left:10px;" src="'.get_option('home').'/wp-content/themes/mytheme/media/images/triangle_error.gif" width="16" height="16" hspace="5" alt=""><strong>Please check the following and try again:</strong></p><ul style="margin-left:50px;">';
// Get each error and add it to the error string
// as a list item.
foreach ($arrErrors as $error) {
$strError .= "<li style='list-style-type:circle;'><em>$error</em></li>";
}
$strError .= '</ul></div><br />';
}
}// NOT BEEN SUBMITTED
// show regular page with form
?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="post" id="post-<?php the_ID(); ?>">
<h2>
<?php the_title(); ?>
</h2>
<?php
// show errors if there is any
echo $strError;
?>
<?php
// show thank you if successful
echo $strGood;
?>
<?php the_content('<p>Read the rest of this page »</p>'); ?>
<form method="post" action="<?php bloginfo('url');?>/your-form-page/" enctype="multipart/form-data">
<input type="hidden" value="send" name="action">
<p <?php if (!empty($arrErrors['name'])) echo ' class="formerror"'; ?>>Your Name:
<span class="errortext" style="color:#F00;">(required)</span><br>
The rest of the form below here ------ >
</form>
<?php endwhile; endif; ?>
<?php get_footer(); ?>
thats it, once the user fills out the form, (my form had a lot more fields than this plus an upload field for files to be attached also.)
but the forms submitted, checks for required fields, if successful it will create a pdf file from the $strContent variable, then attaches this to the email to be sent using the wp_mail from wordpress.. then displays a thank you message, or else it will show and highlight any errors,
hope this helps..
I found these plugins that allow posts to be emailed or downloaded as pdf's.
http://wordpress.org/extend/plugins/tags/create-pdf
If you are flexible, It seems possible to programmatically create posts from your form submitted by a user, then create a pdf of that post. The posts that are created from the form could easily be assigned a particular category which is not displayed on the site.
To programmatically create, update, and delete posts, see the WordPress Function Reference, and in particular:
wp_insert_post
wp update post
wp delete post
A quick google search exhibits plenty of ways to create pdf's with php. Some hard, some less hard. I found this class that might get you started: "FPDF"
There is a plugin extension called Gravity PDF, that extends from Gravity Forms. It will generate a PDF from a form, and you can choose to download or email it.
Source
https://wordpress.org/plugins/gravity-forms-pdf-extended/
I haven't done an exhaustive search of the WP-plugins, but from as far as I can tell the answer is no. Of course, it would be possible to create such a plugin from scratch however the server hosting WP would need to have the proper libraries installed in order for the plugin to be useful.
We created a custom solution for one of our clients to get this done since there weren't any ready available plugins. This system creates pdf/word documents by fetching data from Gravity Forms.
You can check out details of the solution here. Gravity Forms to PDF/Word Document Auto-Fill Soluion