खोज…


टिप्पणियों

यह लाइफ़रे पोर्टल के साथ संस्करण 6.2 तक काम करता है।

जेएसपी हुक

JSP हुक एक विशेष जीवनरक्षक प्लगइन है जो कोर पोर्टलेट jsp-s को संशोधित करने की अनुमति देता है, इससे आप Welcome in my custom login! दिखाने के लिए लॉगिन पोर्टलेट को संशोधित कर सकते हैं Welcome in my custom login!

एक हुक प्लगिन के लिए न्यूनतम संरचना निम्नानुसार है:

[project-name]-hook/
 └── docroot/
     ├── WEB-INF/
     │   ├── src/
     │   ├── lib/
     │   ├── liferay-hook.xml
     │   ├── liferay-plugin-package.properties
     │   └── web.xml
     └── META-INF/
         ├── custom_jsps/
         └── MANIFEST.MF

liferay-hook.xml वह फ़ाइल है जो आपके द्वारा उपयोग किए जा रहे हुक के प्रकार को liferay-hook.xml है, यहां आप हुक के अंदर परिभाषित करते हैं हुक के लिए उचित पैरामीटर JSP हुक के लिए:

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">

<hook>
    <custom-jsp-dir>/custom_jsps</custom-jsp-dir>
</hook>

login.jsp को Liferay में /docroot/html/portlet/login/login.jsp में पाया जाता है, इसका एक हुक बनाने के लिए हमें अपने custom_jsps फ़ोल्डर में समान नाम और पथ के साथ एक jsp जोड़ना होगा।

जब हुक परिनियोजित किया जाता है, तो Liferay, liferay-hook.xml custom-jsp-dir मान के लिए liferay-hook.xml में दिखेगा और इस निर्देशिका में पाए गए सभी पोर्टल custom-jsp-dir को बदल देगा। मूल jsp के नाम के साथ सहेजे जाते हैं <orginal name>.portal.jsp हुक अनिर्धारण के मामले में बहाल किया जाना है।

हम नए संशोधित JSP में भी मूल JSP को कॉल कर सकते हैं यदि हम कोड को अंतर्निहित Liferay प्लेटफ़ॉर्म संस्करण के अपडेट या अपग्रेड के लिए अनुकूल बनाना चाहते हैं। ऐसा करने के लिए, अपने कस्टम JSP में निम्न पैटर्न का उपयोग करें:

<liferay-util:buffer var="contentHtml">
    <liferay-util:include page="/html/{ JSP file’s path }" />
</liferay-util:buffer>

जहाँ इस मामले में { JSP file's path } portlet/login/login.portal.jsp । ऐसा करने को मूल jsp का विस्तार कहा जाता है।

तब हम इसके साथ सामग्री जोड़ सकते हैं:

<%
contentHtml = StringUtil.add("Stuff I'm adding BEFORE the original content", contentHtml,"\n");    
contentHtml = StringUtil.add(contentHtml,"Stuff I'm adding AFTER the original content","\n");
%>
<%= contentHtml %>

स्ट्रट्स एक्शन हुक

इस प्रकार के हुक का उपयोग कोर पोर्टल (जैसे c/portal/login ) और पोर्टलेट स्ट्रट्स क्रियाओं (जैसे /login/forgot_password ) को ओवरराइड करने के लिए किया जा सकता है, Liferay पोर्टल के लिए यह कार्य इसके WEB-INF में एक struts-config.xml फ़ाइल में निर्दिष्ट हैं। WEB-INF फ़ोल्डर। किसी कार्य को ओवरराइड करने के लिए:

  1. docroot/WEB-INF तहत अपने हुक प्लगइन की liferay-hook.xml फ़ाइल में, हुक तत्व के भीतर एक struts-action तत्व जोड़ें।
  2. struts-action एलिमेंट के अंदर, struts-action-path जोड़ें जो आपके द्वारा ओवरराइड कर रहे एक्शन पथ को निर्दिष्ट करता है और struts-action-impl जो आपके कस्टम एक्शन क्लास को निर्दिष्ट करता है। यह struts-action-impl तरह दिखता है:
 <struts-action-path>/login/login</struts-action-path>
    <struts-action-impl>
    com.myhook.action.ExampleStrutsPortletAction
    </struts-action-impl>
</struts-action> 
  1. एक स्ट्रट्स BaseStrutsPortletAction एक्शन क्लास बनाएं जो BaseStrutsPortletAction बढ़ाता है। इस वर्ग का एक उदाहरण है:
 public class ExampleStrutsPortletAction extends BaseStrutsPortletAction {

        public void processAction(StrutsPortletAction originalStrutsPortletAction,
                PortletConfig portletConfig, ActionRequest actionRequest,
                ActionResponse actionResponse) throws Exception {

            System.out.println("Custom Struts Action");

            originalStrutsPortletAction.processAction(originalStrutsPortletAction,
                    portletConfig, actionRequest, actionResponse);
        }

    public String render(StrutsPortletAction originalStrutsPortletAction,
            PortletConfig portletConfig, RenderRequest renderRequest,
            RenderResponse renderResponse) throws Exception {

        System.out.println("Custom Struts Action");

        return originalStrutsPortletAction.render(null, portletConfig,
                renderRequest, renderResponse);
    }
}

originalStrutsPortletAction.processAction स्ट्राट्सपॉर्टलेटएशन.प्रोसेसएशन की तरह ओवरराइड होने वाली विधि को कॉल करना, लाइफ़रे पोर्टल के संबंध में एक्शन से व्यवहार को अपरिवर्तित रखने के लिए अनिवार्य नहीं बल्कि एक सर्वोत्तम अभ्यास है। इस प्रकार के हुक का उपयोग नए स्ट्रट्स liferay-hook.xml को जोड़ने के लिए भी किया जा सकता है, यह एक मौजूदा एक्शन को संशोधित करने के समान है, इस मामले में liferay-hook.xml होगा:

<struts-action>
    <struts-action-path>/my/custom/path</struts-action-path>
    <struts-action-impl>
    com.myhook.action.ExampleStrutsAction
    </struts-action-impl>
</struts-action>

हैलो उपयोगकर्ता "नाम" हुक के साथ

यह उदाहरण दिखाएगा कि लॉगिन के बाद एक सरल "हैलो उपयोगकर्ता [नाम]" कैसे बनाया जाए। उदाहरण हुक का उपयोग करके एक कस्टम क्रिया करने पर आधारित है

अपने कमांड लाइन टर्मिनल से, अपने प्लगइन्स एसडीके के हुक फ़ोल्डर में नेविगेट करें। हुक प्रोजेक्ट बनाने के लिए, आपको क्रिएट स्क्रिप्ट को निष्पादित करना होगा। यहाँ स्क्रिप्ट निष्पादित करने में पालन करने के लिए प्रारूप है:

बनाएँ। [sh | bat] [प्रोजेक्ट-नाम] "[हुक प्रदर्शन नाम]"

लिनक्स और मैक ओएस एक्स पर, आप इस उदाहरण में एक के समान कमांड दर्ज करेंगे:

./create.sh हैलो-उपयोगकर्ता "हैलो उपयोगकर्ता"

विंडोज पर, आप इस उदाहरण में एक के समान कमांड दर्ज करेंगे:

create.bat हैलो-यूजर "माई हुक"

Liferay IDE के नए प्रोजेक्ट विज़ार्ड और बनाएँ स्क्रिप्ट आपके प्लगिन SDK के हुक फ़ोल्डर में हुक प्रोजेक्ट उत्पन्न करते हैं। प्लगइन्स SDK स्वचालित रूप से आपके प्रोजेक्ट नाम में "-hook" जोड़ देता है।

चाहे आपने अपना हुक प्रोजेक्ट Liferay IDE से बनाया हो या कमांड लाइन से, आप एक ही प्रोजेक्ट स्ट्रक्चर के साथ समाप्त होते हैं (पहले देखें)।

  • उस घटना को निर्धारित करें जिस पर आप अपनी कस्टम कार्रवाई को ट्रिगर करना चाहते हैं। मिलान इवेंट प्रॉपर्टी को खोजने के लिए portal.properties प्रलेखन में देखें। संकेत: ईवेंट गुण उनके नाम में .event हैं। सत्र, स्टार्टअप, बंद, और पोर्टल घटना गुण portal.properties दस्तावेज के निम्न अनुभागों में हैं: सत्र - स्टार्टअप घटनाक्रम - शटडाउन घटनाक्रम - पोर्टल घटनाक्रम
  • अपने हुक प्रोजेक्ट में, एक जावा क्लास बनाएं जो com.liferay.portal.kernel.events.Action क्लास तक फैली हो Action.run (HttpServletRequest, HttpServletResponse) विधि को ओवरराइड करें।
       import com.liferay.portal.kernel.events.Action;
       import javax.servlet.http.HttpServletRequest;
       import javax.servlet.http.HttpServletResponse;
       import com.liferay.portal.model.User;
       import com.liferay.portal.util.PortalUtil;

       public class HelloUser extends Action {
           public void run(HttpServletRequest req, HttpServletResponse res) {
               User user = PortalUtil.getUser(req);
               System.out.println("Hello User "+user.getScreenName());
           }
       }

महत्वपूर्ण: यदि आपका एक्शन HttpServletRequest ऑब्जेक्ट पर पहुंचता है, तो com.liferay.portal.kernel.events.Action का विस्तार करें; अन्यथा, com.liferay.portal.struts.SimpleAction का विस्तार करें।

  • अपने हुक प्रोजेक्ट के डॉकरॉट / WEB-INF / src फ़ोल्डर के अंदर एक गुण फ़ाइल, portal.properties बनाएँ। फिर उस पोर्टल ईवेंट प्रॉपर्टी का नाम जोड़ें जो उस ईवेंट से मेल खाती है जिस पर आप अपनी कार्रवाई करना चाहते हैं। संपत्ति के मूल्य के रूप में अपने एक्शन क्लास को पूरी तरह से योग्य नाम निर्दिष्ट करें।

    `login.events.post=HelloUser`
    

    उदाहरण के लिए, उपयोगकर्ता में पोर्टल लॉगिंग से ठीक पहले एक वर्ग की कार्रवाई करने के लिए, आप अपने एक्शन क्लास के साथ उसके मूल्य के रूप में login.events.pre संपत्ति निर्दिष्ट करेंगे। यह इस संपत्ति सेटिंग की तरह लग सकता है।

महत्वपूर्ण: चूँकि पोर्टल प्रॉपर्टीज जैसे login.events.pre कई मानों को स्वीकार करती है, आपको अपने मूल्यों को मौजूदा मूल्यों के साथ जोड़ना होगा। आप अतिरिक्त हुक से गुणों को बार-बार संशोधित कर सकते हैं।

केवल एक पोर्टल संपत्ति को संशोधित करें जो एकल हुक प्लगइन से एकल मान को स्वीकार करता है। यदि आप कई प्लगइन्स से किसी प्रॉपर्टी की वैल्यू को संशोधित करते हैं, तो लाइफ़रे को पता नहीं चलेगा कि किस वैल्यू का उपयोग करना है।

  • अपनी docroot / WEB-INF / liferay-hook.xml फ़ाइल को संपादित करें और अपना जोड़ें
    हुक के पोर्टल गुण फ़ाइल नाम के लिए मान के रूप में
    <portal-properties>...</portal-properties> तत्व
    हुक का <hook>...</hook> तत्व। उदाहरण के लिए, यदि आपके हुक के गुण फ़ाइल का नाम portal.properties है , तो आप इस तत्व को निर्दिष्ट करेंगे:
<portal-properties>portal.properties</portal-properties>
  • अपने हुक को तैनात करें, अपने हुक पथ पर जाएं और ant clean deploy आपको दिखाई देगा।

अब यदि आप जीवनकाल में लॉग इन करते हैं, तो आप सर्वर में "हैलो उपयोगकर्ता व्यवस्थापक" जैसे संदेश को देखेंगे।

मॉडल श्रोता हुक

पृष्ठभूमि

मॉडल श्रोता हुक एक प्रकार का Liferay प्लगइन है जो किसी मॉडल पर ली गई घटनाओं को सुनता है और प्रतिक्रिया में कोड निष्पादित करता है। मॉडल श्रोता हुक कस्टम स्ट्रट्स एक्शन हुक के समान हैं जिसमें वे पोर्टल में की गई कार्रवाई का जवाब देते हैं। हालांकि जब स्ट्रट्स कार्रवाई उपयोगकर्ता द्वारा की गई कार्रवाई का जवाब देती है, तो एक मॉडल श्रोता एक लीफ़ेरियन मॉडल से संबंधित एक घटना का जवाब देता है (पहले या बाद में)।


मतभेद

तुलना के लिए स्ट्रेट एक्ट्स वी। मॉडल श्रोताओं के कुछ उदाहरण यहां दिए गए हैं।

  • स्ट्रट्स एक्शन
    • उपयोगकर्ता लॉगिन
    • खाता निर्माण
    • सत्र का विस्तार करें
    • फ़ोल्डर ले जाएँ
  • मॉडल श्रोता
    • फोल्डर बनने के बाद
    • जब उपयोगकर्ता जानकारी अपडेट की जाती है
    • बुकमार्क निकालने के बाद
    • एक भूमिका से पहले एसोसिएशन बनाया जाता है

लाइफरे की वास्तुकला सीखने के लिए सबसे अच्छा संसाधन उनके स्रोत कोड के माध्यम से है। उनकी सभी स्रोत फ़ाइलें GitHub पर और उनके JavaDocs को देखने के द्वारा स्थित हैं। आप JavaDocs पर सभी मुख्य पोर्टल मॉडल और GitHub पर स्ट्रट्स एक्ट के सभी देख सकते हैं


उदाहरण

इस ट्यूटोरियल में हम एक मॉडल श्रोता को विकसित करने जा रहे हैं जो अपने खाते को पहली बार बनाने के बाद एक उपयोगकर्ता को एक ईमेल भेजता है। ऐसा करने के लिए हम UserModelListener नामक एक वर्ग लिखने जा रहे हैं, जो Liferay's BaseModelListener का विस्तार करेगा। हम संक्षिप्त रूप से हुक निर्माण पर जाएंगे और आवश्यक संशोधनों को निम्नलिखित कॉन्फिग फाइलों में शामिल करेंगे

  • portal.properties

  • Liferay-hook.xml

शुरू करना

अपने मॉडल श्रोता हुक को विकसित करने के लिए आपको पहले अपना लाइफ़रे आईडीई या लाइफ़रे डेवलपर स्टूडियो एप्लिकेशन लॉन्च करना होगा।

Liferay IDE और Liferay Developer Studio दोनों ही ग्रहण विकास के वातावरण में अनुकूलित हैं। वे हड़ताली समान हैं और दिशाओं का एक सेट दोनों वातावरणों के लिए पर्याप्त होना चाहिए।

अपने विकास के वातावरण के अंदर निम्नलिखित चरणों का पालन करें।

  1. ऊपरी बाएँ कोने में फ़ाइल पर क्लिक करें
  2. अपने माउस को नए पर होवर करें
  3. Liferay Plugin Project पर क्लिक करें

आप इस विंडो को स्पॉन करेंगे।

यहाँ छवि विवरण दर्ज करें

कृपया ऊपर दी गई जानकारी दर्ज करें

  • परियोजना का नाम: उपयोगकर्ता-मॉडल-श्रोता
  • डिफ़ॉल्ट स्थान का उपयोग करें चुनें
  • बिल्ड प्रकार: चींटी
  • प्लगइन प्रकार: हुक

सुनिश्चित करें कि आपका प्रोजेक्ट आपके Liferays प्लगइन्स SDK हुक निर्देशिका के अंदर स्थित है। आपको तदनुसार अपने एसडीके और अपने रनटाइम का चयन करना होगा।

अपने पैकेज एक्सप्लोरर परिप्रेक्ष्य में आप निम्न निर्देशिका संरचना देखेंगे।

यहाँ छवि विवरण दर्ज करें


श्रोता विकास

अब जब आपने अपना हुक बना लिया है तो आपको अपना कस्टम UserModelListener वर्ग बनाना होगा। यह वर्ग लाइफ़रे के बेसमॉडलिस्टनर वर्ग का विस्तार करेगा।

Liferay's BaseModelListener वर्ग एक अमूर्त वर्ग है जो ModelListener इंटरफ़ेस को लागू करता है। आप ModelListener इंटरफ़ेस को सीधे लागू नहीं करना चाहते हैं क्योंकि इसके लिए आपको इसके सभी तरीकों को ओवरराइड करना होगा।

निम्न विधियों BaseModelListener सार वर्ग के माध्यम से ModelListener इंटरफ़ेस द्वारा आप के लिए प्रदान की जाती हैं।

  • onAfterAddAssociation
  • onAfterCreate
  • onAfterRemove
  • onAfterRemoveAssociation
  • onAfterUpdate
  • onBeforeAddAssociation
  • onBeforeCreate
  • onBeforeRemove
  • onBeforeRemoveAssociation
  • onBeforeUpdate

निम्नलिखित निर्देशिका के अंदर अपना UserModelListener वर्ग बनाएं। जीयूआई के माध्यम से वर्ग बनाने के लिए बस निम्नलिखित कमांड निष्पादित करें

  • ऊपरी बाएँ कोने में फ़ाइल पर क्लिक करें
  • अपने माउस को नए पर होवर करें
  • कक्षा पर क्लिक करें
docroot/
     WEB-INF/
           src/

नीचे दी गई जानकारी दर्ज करें

यहाँ छवि विवरण दर्ज करें

अपने UserModelListener वर्ग के अंदर निम्न कोड चिपकाएँ

package com.example.hook;

import com.liferay.mail.service.MailServiceUtil;
import com.liferay.portal.ModelListenerException;
import com.liferay.portal.kernel.mail.MailMessage;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.BaseModelListener;
import com.liferay.portal.model.User;


import javax.mail.internet.InternetAddress;

public class UserModelListener extends BaseModelListener<User> {
    private User user = null;

    @Override
    public void onAfterCreate(User user) throws ModelListenerException {
    this.user = user;
    
    if(isValidEmail()) {
        sendEmail("[email protected]", user.getEmailAddress(), "Welcome!", "Your account is created!");
    } 
    }

    private boolean isValidEmail() {
    return Validator.isNotNull(user.getEmailAddress()) && Validator.isAddress(user.getEmailAddress());
    }
    
    private void sendEmail(String from, String to, String subject, String body) {
    try {
        MailServiceUtil.sendEmail(new MailMessage(new InternetAddress(from), new InternetAddress(to), subject, body, false));
    } catch (Exception e) {
        System.err.print("E-Mail spawned by User Model Listener failed to " + user.getFullName() + " with message " + e.getMessage());
    }
    }
}

गुण विन्यास

हमारे कस्टम श्रोता और हमारे मॉडल के बीच सहयोग को कॉन्फ़िगर करने के लिए हमें कुछ अंतिम समायोजन करने की आवश्यकता है। सबसे पहले, निम्न निर्देशिका में एक नया portal.properties फ़ाइल बनाएँ।

docroot/
     WEB-INF/
           src/
            + portal.properties

फ़ाइल में केवल एक पंक्ति को जोड़ना होगा।

value.object.listener.com.liferay.portal.model.User = com.example.hook.UserModelListener

हम यह कहकर इसका सामान्यीकरण कर सकते हैं, किसी भी मॉडल श्रोता के लिए हम संबंधित गुण मान बनाते हैं जो के रूप में होना चाहिए

value.object.listener.fully.qualified.model.name = fully.qualified.listener.name

दूसरे शब्दों में, यदि हमने एक CustomerDLFolderModelListener वर्ग लिखा है, तो com.example.code के अंदर पैक किया गया है, DLFolder मॉडल के लिए हमारे पास निम्नलिखित संपत्ति होगी

value.object.listener.com.liferay.portal.model.DLFolder = com.example.code.CustomerDLFolderModelListener 

अंत में, अपने जीवनकाल-हुक.xml फ़ाइल का पता लगाएं। स्रोत दृश्य में, निम्नलिखित लिखें।

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">

<hook>
    <portal-properties>portal.properties</portal-properties>
</hook>

व्याख्या

  1. लाइन एक एक वैकल्पिक प्रोलॉग है जो दस्तावेज़ संस्करण और (कुछ मामलों में) वर्ण सेट को निर्दिष्ट करता है।
  2. लाइन 2 एक औपचारिक डॉक टाइप परिभाषा (DTD) है जो स्पष्ट रूप से परिभाषित करता है कि कौन से तत्व और गुण मान्य हैं
  3. लाइन 3 और 5 मूल हुक तत्व से मिलकर बनता है (इस DTD द्वारा समर्थित वैध तत्वों में से एक)
  4. लाइन 4 ओवरराइड करती है और $ {liferay.home} में portal.properties फ़ाइल का विस्तार करती है

यह देखने के लिए कि इस XML फ़ाइल में और कौन से तत्व इस्तेमाल किए जा सकते हैं, आप URL को DocType परिभाषा में संदर्भित कर सकते हैं। यह DTD वाली सभी XML और SGML फाइलों के लिए मानक है। एक DTD के साथ Liferay XML फ़ाइल का एक और उदाहरण सेवा है Xml ( हाइबरनेट पर आधारित Liferay का ORM कार्यान्वयन)।


निर्माण और तैनात करें

हुक का निर्माण और तैनाती एक सरल प्रक्रिया है। Liferay प्लगइन विकास के साथ निर्माण और निर्भरता स्वचालन का समर्थन करता है

  • चींटी
  • आइवी लता
  • Maven
  • Gradle

हमारे उदाहरण में हमने बिल्ड ऑटोमेशन के लिए चींटी का इस्तेमाल किया। बिल्ड. xml फ़ाइल में बिल्ड कमांड ( चींटी में लक्ष्य के रूप में जाना जाता है) शामिल हैं। अपना हुक बनाने के लिए बस निम्नलिखित कमांड निष्पादित करें।

  1. अपनी build.xml फ़ाइल स्थित है
  2. अपने IDE में, Ant.xml फ़ाइल को चींटी के परिप्रेक्ष्य में खींचें
  3. फ़ाइल का विस्तार करें और सभी लक्ष्य चलाएँ

यहाँ छवि विवरण दर्ज करें

अपने कंसोल दृश्य में आपको निम्नलिखित के समान कुछ देखना चाहिए

Buildfile: C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\build.xml
all:
clean:
   [delete] Deleting directory C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
clean-portal-dependencies:
compile:
merge:
compile-import-shared:
    [mkdir] Created dir: C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
     [copy] Copying 5 files to C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\lib
compile-java:
     [copy] Copied 3 empty directories to 3 empty directories under C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
    [javac] Compiling 1 source file to C:\liferay-plugins-sdk-6.2-ee-sp11\hooks\User-Listener-Hook-hook\docroot\WEB-INF\classes
merge:
war:
clean-portal-dependencies:
      [zip] Building zip: C:\liferay-plugins-sdk-6.2-ee-sp11\dist\User-Listener-Hook-hook-6.2.10.1.war
deploy:
     [copy] Copying 1 file to C:\liferay-portal-6.2-ee-sp11\deploy
BUILD SUCCESSFUL
Total time: 7 seconds

अपने हुक के साथ सफलतापूर्वक बनाया गया अब आपके पोर्टल को शुरू करने और इसे तैनात करने का समय है। अपना सर्वर शुरू करने और हुक को तैनात करने के लिए सर्वर परिप्रेक्ष्य का पता लगाएं।

  1. अपने सर्वर पर राइट क्लिक करें और जोड़ें या निकालें पर क्लिक करें
  2. उपलब्ध चयन के तहत उपयोगकर्ता-श्रोता-हुक का पता लगाएँ
  3. एक बार हाइलाइट होने के बाद Add बटन पर क्लिक करें और OK पर क्लिक करें
  4. सर्वर परिप्रेक्ष्य में प्ले बटन पर क्लिक करें

यहाँ छवि विवरण दर्ज करें



कृपया मुझे बताएं कि क्या आपके पास कोई प्रश्न, टिप्पणी, चिंताएं आदि हैं, सभी रचनात्मक प्रतिक्रिया की बहुत सराहना की जाती है!





Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow