मैं जूमला के लिए एक कस्टम घटक विकसित कर रहा हूं! 3.x और कुछ डेटा पुनः प्राप्त करने के लिए इसके अंदर एक AJAX कॉल करना चाहते हैं। इसे करने का उचित तरीका क्या है?
मैं जूमला के लिए एक कस्टम घटक विकसित कर रहा हूं! 3.x और कुछ डेटा पुनः प्राप्त करने के लिए इसके अंदर एक AJAX कॉल करना चाहते हैं। इसे करने का उचित तरीका क्या है?
जवाबों:
कृपया ध्यान दें कि यह उत्तर पहले से ही कुछ साल पुराना है और अद्यतन नहीं किया गया था। अगर आपको लगता है कि कुछ ठीक नहीं है, तो संपादित करें / टिप्पणी के लिए स्वतंत्र महसूस करें।
इससे निपटने का लगभग कोई आधिकारिक तरीका नहीं है, यह बहुत जटिलता पर निर्भर करता है और आप काम करने के लिए एमवीसी पैटर्न पर कितना भरोसा करना चाहते हैं।
नीचे कुछ संभावित उपाय दिए गए हैं जो जूमला 2.5 और 3.x में काम करना चाहिए। कोड को कॉपी पेस्ट नौकरी के लिए प्रस्तुत नहीं किया जाता है, बल्कि एक सामान्य विचार के रूप में प्रस्तुत किया जाता है।
जुमला से पहले! 3.2 केवल एक चीज जिसे आपको नीचे दिए गए उदाहरणों का उपयोग करने की आवश्यकता है, एक है component
। जूमला 3.2 (कम जटिल कार्यों के लिए) के बाद आप मॉड्यूल और प्लगइन्स के अनुरोध को संभाल सकते हैं।
कार्य के लिए आपका URL इस तरह दिखना चाहिए:
index.php?option=com_similar&task=abc&format=raw
आप नियंत्रक का निर्माण करते हैं जो दृश्य का उपयोग करेगा, आइए Abc
बताते हैं , जिसमें फ़ाइल view.raw.html (सामान्य दृश्य फ़ाइल के समान) होगी।
नीचे आपके पास एक कच्चा HTML प्रतिक्रिया उत्पन्न करने के लिए कोड है:
/controller.php
public function abc()
{
// Set view
// Joomla 2.5
JRequest::setVar('view', 'Abc');
// (use JInput in 3.x)
$this->input->set('view', 'Abc');
parent::display();
}
/views/abc/view.raw.php
<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.view');
class SimilarViewAbc extends JViewLegacy
{
function display($tpl = null)
{
parent::display($tpl);
}
}
/views/abc/tmpl/default.php
<?php
echo "Hello World from /views/abc/tmpl/default.php";
नोट: यह वह समाधान है जो मुझे उपयोग करना होगा यदि मुझे HTML लौटना है (यह क्लीनर है और जूमला तर्क का अनुसरण करता है)। साधारण JSON डेटा वापस करने के लिए, नियंत्रक में सब कुछ कैसे रखा जाए, नीचे देखें।
यदि आप अपने अजाक्स को उप- नियंत्रक से अनुरोध करते हैं , जैसे:
index.php?option=com_similar&controller=abc&format=raw
अपने उपमहाद्वीप के नाम (कच्चे दृश्य के लिए) से अधिक होना चाहिए abc.raw.php
।
इसका मतलब यह भी है कि आपके पास एबीसी नाम के 2 उप-नियंत्रक होंगे।
यदि आप JSON लौटाते हैं, तो इसका उपयोग करने के लिए समझ में आ सकता है format=json
और abc.json.php
। जूमला 2.5 में। मेरे पास इस विकल्प को काम करने के लिए कुछ विकल्प थे (किसी तरह आउटपुट दूषित हो गया था), इसलिए मैंने कच्चे का उपयोग किया।
यदि आपको एक वैध JSON प्रतिक्रिया उत्पन्न करने की आवश्यकता है , तो डॉक्स पृष्ठ उत्पन्न करें JSON आउटपुट की जाँच करें
// We assume that the whatver you do was a success.
$response = array("success" => true);
// You can also return something like:
$response = array("success" => false, "error"=> "Could not find ...");
// Get the document object.
$document = JFactory::getDocument();
// Set the MIME type for JSON output.
$document->setMimeEncoding('application/json');
// Change the suggested filename.
JResponse::setHeader('Content-Disposition','attachment;filename="result.json"');
echo json_encode($response);
आप आमतौर पर इस कोड को नियंत्रक में डालेंगे (आप एक मॉडल को कॉल करेंगे जो आपके द्वारा एनकोड किए गए डेटा को लौटा देगा - एक बहुत ही सामान्य परिदृश्य)। यदि आपको इसे और आगे ले जाने की आवश्यकता है, तो आप कच्चे उदाहरण के साथ एक JSON व्यू (view.json.php) भी बना सकते हैं।
अब जब अजाक्स अनुरोध काम कर रहा है, तब भी पृष्ठ को बंद न करें। नीचे दिया गया पढ़ें।
अनुरोध forgeries के लिए जाँच करने के लिए मत भूलना। JSession::checkToken()
यहाँ आ जाओ। CSRF को एंटी-स्पूफिंग फॉर्म में कैसे जोड़ा जाए, इस पर प्रलेखन पढ़ें
ऐसा हो सकता है कि यदि आप अनुरोध में भाषा का नाम नहीं भेजते हैं, तो जूमला आपके द्वारा इच्छित भाषा तार का अनुवाद नहीं करेगा।
किसी भी तरह अपने अनुरोध (जैसे &lang=de
) के लिए लंब परम अपील करने पर विचार करें ।
जूमला 3.2 में नया! - आप एक घटक के निर्माण के बिना संभाल अनुरोध करने के लिए सक्षम है
जूमला! अजाक्स इंटरफ़ेस - जुमला अब एक प्लगइन या मॉड्यूल में अजाक्स अनुरोध को संभालने के लिए एक हल्का तरीका प्रदान करता है। आप जूमला का उपयोग करना चाह सकते हैं! Ajax इंटरफ़ेस यदि आपके पास पहले से कोई घटक नहीं है या यदि आपके पास पहले से मौजूद मॉड्यूल से अनुरोध करने की आवश्यकता है।
JRequest
? $this->input
जब मैं v3.x का उपयोग करता हूं, तो यह पदावनत होना चाहिए ?
JRequest
। धन्यवाद
Valid JSON Response
अनुभाग में इसका उल्लेख किया है ।
यह बहुत अच्छी तरह से पूछे गए प्रश्न के लिए एक देर से जवाब है, लेकिन मैं उन लोगों के लिए इस कट-टू-चेस समाधान को जोड़ना चाहता था, जिन्हें बस AJAX कॉल के साथ अपने घटकों के डेटा को प्राप्त करने के लिए एक सरल तरीका चाहिए।
सभी जूमला संस्करणों के साथ, 3 पार्टी की संभावनाएं, और हैक जो मुझे कई दिनों के गोग्लिंग में मिले, यह सबसे सरल दृष्टिकोण था जिसके साथ मैं आ सकता था - और प्रतिक्रिया की सराहना की गई है।
execute
मेरे मौजूदा मुख्य नियंत्रक में फ़ंक्शन जोड़ा गयाकार्य को कॉल / निष्पादित करने के लिए URL:
www.mysite.com/index.php?option=com_example&task=ForAjax.mytaskname
संशोधित मुख्य नियंत्रक \ com_example \ नियंत्रक.php
class ExampleController extends JControllerLegacy {
public function display($cachable = false, $urlparams = false) {
$app = JFactory::getApplication();
$view = $app->input->getCmd('view', 'default');
$app->input->set('view', $view);
parent::display($cachable, $urlparams);
return $this;
}
public function execute()
{
// Not technically needed, but a DAMN good idea. See http://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms
// JSession::checkToken();
$task = JFactory::getApplication()->input->get('task');
try
{
parent::execute($task);
}
catch(Exception $e)
{
echo new JResponseJson($e);
}
}
}
नया उप-नियंत्रक \ com_example \ नियंत्रकों \ forajax.php
require_once JPATH_COMPONENT.'/controller.php';
class ExampleControllerForAjax extends ExampleController
{
public function MyTaskName()
{
$app = JFactory::getApplication();
$data['myRequest'] =$_REQUEST;
$data['myFile'] =__FILE__;
$data['myLine'] ='Line '.__LINE__;
$app->enqueueMessage('This part was reached at line ' . __LINE__);
$app->enqueueMessage('Then this part was reached at line ' . __LINE__);
$app->enqueueMessage('Here was a small warning at line ' . __LINE__, 'warning');
$app->enqueueMessage('Here was a big warning at line ' . __LINE__, 'error');
$task_failed = false;
echo new JResponseJson($data, 'My main response message',$task_failed);
$app->close();
}
}
रेंडर JSON आउटपुट
{
success: true,
message: "My main response message",
messages: {
message: [
"This part was reached at line 26",
"Then this part was reached at line 27"
],
warning: [
"Here was a small warning at line 28"
],
error: [
"Here was a big warning at line 29"
]
},
data: {
myRequest: {
option: "com_example",
task: "mytaskname",
Itemid: null
},
myFile: "C:\mysite\components\com_example\controllers\forajax.php",
myLine: "Line 24"
}
}
वैलेंटाइन का उत्तर अच्छा है, लेकिन थोड़ा अधिक जटिल है अगर आपको बस इतना करना है कि पहले से निर्मित एक घटक में 1 या 2 अजाक्स कॉल जोड़ें। यह अलग controller.raw.php
या view.raw.php
फ़ाइलों को नहीं बनाने के साथ दूर होने के लिए पूरी तरह से संभव है ।
इस अजाक्स कॉल करने के लिए
index.php?format=raw&option=com_example&controller=job&task=keep_alive&tokenhash=1
में job
subcontroller
public function keep_alive() {
$this->ajax_check();
//Do your processing and echo out whatever you want to return to the AJAX call
header('HTTP/1.1 202 Accepted', true, 202);
echo 'OK';
JFactory::getApplication()->close();
}
// Verifies jtoken and does a basic check that this is actually an AJAX call
private function ajax_check() {
if(!JSession::checkToken('GET') || !isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') {
header('HTTP/1.1 403 Forbidden', true, 403);
JFactory::getApplication()->close();
}
}
वैलेंटाइन का जवाब अच्छा है।
मैं एक json नियंत्रक पसंद करता हूँ जो एन्कोडिंग और एरर हैंडलिंग को हैंडल करता है इसके लिए मैंने json base class बनाया है:
class itrControllerJson extends JControllerLegacy {
/** @var array the response to the client */
protected $response = array();
public function addResponse($type, $message, $status=200) {
array_push($this->response, array(
'status' => $status,
'type' => $type,
'data' => $message
));
}
/**
* Outputs the response
* @return JControllerLegacy|void
*/
public function display() {
$response = array(
'status' => 200,
'type' => 'multiple',
'count' => count($this->response),
'messages' => $this->response
);
echo json_encode($response);
jexit();
}
}
यह नियंत्रक नियंत्रक वर्ग द्वारा विस्तारित होता है जो काम करते हैं, कुछ इस तरह से:
require_once __DIR__.'json.php';
class componentControllerAddress extends itrControllerJson {
public function get() {
try {
if (!JSession::checkToken()) {
throw new Exception(JText::_('JINVALID_TOKEN'), 500);
}
$app = JFactory::getApplication();
$id = $app->input->get('id', null, 'uint');
if (is_null($id)) {
throw new Exception('Invalid Parameter', 500);
}
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__table');
$query->where('id = '.$db->quote($id));
$db->setQuery($query);
$response = $db->loadObject();
$this->addResponse('message', $response, 200);
} catch (Exception $e) {
$this->addResponse('error', $e->getMessage(), 500);
}
$this->display();
}
}
और आप इस तरह से अनुरोध करते हैं:
index.php?option=com_component&task=address.get&format=json&id=1234&tokenhash=1
टोकन हैश जेसेशन द्वारा प्राप्त किया जाता है :: getFormToken ()। तो पूरा पूरा कॉल इस तरह दिख सकता है:
$link = JRoute::_('index.php?option=com_component&task=address.get&format=json&id=1234&'.JSession::getFormToken().'=1', false);
दूसरा पैरामीटर "झूठा" पर सेट है, इसलिए हम इसे एक्सएमएल रीराइट के बिना जावास्क्रिप्ट कॉल में उपयोग कर सकते हैं।
JResponseJson
इसे संभालने के लिए कक्षा का उपयोग क्यों नहीं किया गया?
यदि आप 100% सुनिश्चित हैं कि कोई जावास्क्रिप्ट-आउटपुट प्लगइन नहीं है, तो किसी भी जावास्क्रिप्ट आउटपुट को जोड़ने पर, शुद्ध json_encode ठीक काम करता है।
लेकिन ... उदाहरण के लिए JomSocial पूरी साइट पर "" जोड़ता है।
तो ... टैग्स के साथ एक आसान ट्रिक, json_encode लपेटें और इसे जावास्क्रिप्ट पक्ष पर संसाधित करें।
echo '@START@' . json_encode(...) . '@END@';
आप कार्य में नियंत्रक नाम का उपयोग करके किसी नियंत्रक को सीधे एक्सेस कर सकते हैं:
index.php?option=com_similar&task=controller.abc&format=raw
कॉल करेगा: कंट्रोलर। क्र.फपी (रिटर्न कच्चा है)
index.php?option=com_similar&task=controller.abc
कॉल करेगा: कंट्रोलर। एफपी (यदि आप उपयोग नहीं करते हैं तो रिटर्न html है die;
)