पृष्ठभूमि अनुवाद Pt. 3 (हिन्दी (Hindi))

पृष्ठभूमि अनुवाद Pt. 3

Sunday, 25 August 2024

//

11 minute read

परिचय

पिछले लेखों में हम ने वेब अनुप्रयोगों के संदर्भ में अनुवाद की महत्व पर चर्चा की है।

फिर से, आप अपने पर इस के लिए सभी स्रोत कोड देख सकते हैं जिटहब पृष्ठ

पिछली अनुच्छेद

यहाँ हम एक छोटा उपकरण जोड़ते हैं जो पृष्ठभूमि कार्यों को सेवा में हम भाग में विनिर्दिष्ट करने के लिए प्रस्तुत करता है 2. यह उपकरण एक सरल फार्म है कि आपको सेवा में अनुवाद अनुरोध प्रस्तुत करने की अनुमति देता है।

यह कार्यात्मकता जोड़ता है जहां जब आप एक 'new' दस्तावेज चुनते हैं तो आप इसे अनुवाद कर सकते हैं

संपादक

अनुवाद कोड

अनुवाद प्रेषक

हमारे मार्कडाउन संपादक पृष्ठ पर मैंने कुछ कोड जोड़ा, जिसमें एक छोटा ड्रॉप डाउन (in है _LanguageDropDown.cshtml) जो आपको अनुवाद करने के लिए भाषा चुनने की अनुमति देता है

        @if (Model.IsNew)
                {
                    var translationHidden = Model.TranslationTasks.Any() ? "" : "hidden";
              
                    <p class="text-blue-dark dark:text-blue-light inline-flex  items-center justify-center space-x-2">
                        <partial name="_LanguageDropDown" for="Languages"/>
                        <button class="btn btn-outline btn-sm mt-1" x-on:click="window.mostlylucid.translations.submitTranslation"><i class='bx bx-send'></i>Translate</button>
                    </p>
                    <div id="translations" class="@translationHidden">
                        <partial name="_GetTranslations" model="Model.TranslationTasks" />
                    </div>
                    <div id="translatedcontent" class="hidden">
                        <textarea class="hidden" id="translatedcontentarea"></textarea>
                    </div>
                }

_भाषा ड्रपडाउन

हमारे _LanguageDropDown आंशिक दृश्य एक सरल ड्रॉप डाउन है जो आपको भाषा चुनने की अनुमति देता है जिसे आप अनुवाद करना चाहते हैं Languages मॉडल का गुण

आप देख सकते हैं कि यह Alpine का उपयोग करता है.js ड्रॉप डाउन को संभालने और मुख्य चयन भाग में दिखाने के लिए चुना गया भाषा और झंडा सेट करने के लिए प्रयोग किया जाता है

अल्पिंग का उपयोग करने से हम न्यूनतम रखते हैं, स्थानीय संदर्भित जावास्क्रिप्ट को हमारे दृश्यों में रखें

@using Mostlylucid.Helpers
@model List<string>

<div id="LanguageDropDown" x-data="{ 
    open: false, 
    selectedLanguage: 'Select Language', 
    selectedFlag: '' ,
    selectedShortCode:''
}" class="relative inline-block mt-3">
    <!-- Dropdown Button -->
    <button x-on:click="open = !open" class="btn btn-sm btn-outline flex items-center space-x-2">
        <!-- Dynamically Show the Flag Icon -->
        <template x-if="selectedFlag">
            <img :src="selectedFlag" class="h-4 w-4 rounded outline outline-1  outline-green-dark dark:outline-white" alt="Selected Language Flag">
        </template>
        <span x-text="selectedLanguage"></span>
        <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ml-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
        </svg>
    </button>

    <!-- Dropdown Menu -->
    <div x-show="open" x-on:click.away="open = false"
         class="absolute left-0 mt-2 w-64 rounded-md shadow-lg dark:bg-custom-dark-bg bg-white ring-1 ring-black ring-opacity-5 z-50">
        <ul class="p-2">
            @foreach (var language in Model)
            {
            <li>
                <a href="#"
                   x-on:click.prevent="selectedLanguage = '@(language.ConvertCodeToLanguage())'; selectedFlag = '/img/flags/@(language).svg'; selectedShortCode='@language'; open = false"
                   class="flex dark:text-white text-black items-center p-2 hover:bg-gray-100">
                    <img src="/img/flags/@(language).svg" asp-append-version="true" class="ml-2 h-4 w-4 mr-4 rounded outline outline-1  outline-green-dark dark:outline-white" alt="@language"> @language.ConvertCodeToLanguage()
                </a>
            </li>
            }
        </ul>
    </div>
</div>

अनुवाद प्रस्तुत करें

आप' देखेंगे कि यह कुछ Apline .js कोड है जो हमारे में कॉल करता है window.mostlylucid.translations.submitTranslation फंक्शन. यह फ़ंक्शन हमारे में परिभाषित है translations.js फाइल जो हमारे में शामिल है _Layout.cshtml फ़ाइल.

export function submitTranslation() {
    const languageDropDown = document.getElementById('LanguageDropDown');

    // Access Alpine.js data using Apline.$data (Alpine.js internal structure)
    const alpineData = Alpine.$data(languageDropDown);
const shortCode = alpineData.selectedShortCode;
const markdown = simplemde.value();
if (shortCode === '' || markdown === '') return;
    
    // Create the data object that matches your model
    const model = {
        Language: shortCode,
        OriginalMarkdown: markdown
    };

// Perform the fetch request to start the translation using POST
    fetch('/api/translate/start-translation', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'  // The content type should be JSON
        },
        body: JSON.stringify(model)  // Send the data object as JSON
    })
        .then(function(response) {
            if (response.ok) {
                // Process the returned task ID
                return response.json();  // Parse the JSON response (assuming the task ID is returned in JSON)
            } else {
                console.error('Failed to start the translation');
            }
        })
        .then(function(taskId) {
            if (taskId) {
                console.log("Task ID:", taskId);

                // Trigger an HTMX request to get the translations after saving
                htmx.ajax('get', "/editor/get-translations", {
                    target: '#translations',  // Update this element with the response
                    swap: 'innerHTML',        // Replace the content inside the target
                }).then(function () {
                    // Remove the hidden class after the content is updated
                    document.getElementById('translations').classList.remove('hidden');
                });
            }
        })
        .catch(function(error) {
            // Handle any errors that occur during the fetch
            console.error('An error occurred:', error);
        });

अनुक्रम रेखाचित्र

यह कोड निम्नलिखित अनुक्रम चित्र में वर्णित है

sequenceDiagram
    autonumber
    actor User
    participant JS as Client JS
    participant Alpine as Alpine.js
    participant FetchAPI as Fetch API
    participant HTMX as HTMX

    User->>JS: Trigger submitTranslation()
    JS->>Alpine: Access data from LanguageDropDown via Alpine.js
    Alpine-->>JS: Return selectedShortCode and markdown
    JS->>JS: Check if shortCode and markdown are not empty
    alt shortCode or markdown is empty
        JS->>User: Do nothing
    else
        JS->>FetchAPI: Send POST request with model {Language, OriginalMarkdown}
        FetchAPI-->>JS: Return taskId in JSON response
        alt response is ok
            JS->>HTMX: Send GET request to /editor/get-translations via HTMX
            HTMX-->>JS: Return updated translations
            JS->>DOM: Remove 'hidden' class from translations element
        else
            JS->>Console: Log "Failed to start the translation"
        end
    end
    JS->>Console: Handle any fetch errors

हालांकि यह बहुत कोड की तरह दिखता है

  1. हम भाषा और मार्क डाउन सामग्री के साथ सर्वर को एक POST अनुरोध भेजें. यह एक अंत बिंदु बुलाया जाता है start-translation जो हमारे में परिभाषित है TranslationAPIयह अनुवाद कार्य को आरंभ करता है और इस उपयोक्ता के लिए कैश में यह कार्य जोड़ता है

  2. सर्वर एक कार्य आईडी के साथ प्रतिक्रिया देता है (जो हम लॉग करें लेकिन नहीं करते हैं

  3. तब हम अनुवाद प्राप्त करने के लिए सर्वर को एक GET निवेदन भेजते हैं

प्रारंभ अनुवाद अंतबिन्दु

यह एक वेब एपीआई नियंत्रक है जो मार्कडाउन और भाषा कोड सहित अनुरोध लेता है। (मैं वैलिडेट एन्टीफ़ॉर्जी टोकन विशेषता को अब अक्षम कर दिया है क्योंकि मैं इसे उपयोग नहीं करता हूँ

    [HttpPost("start-translation")]
   // [ValidateAntiForgeryToken]
    public async Task<Results<Ok<string>, BadRequest<string>>> StartTranslation([FromBody] MarkdownTranslationModel model)
    {
        if(ModelState.IsValid == false)
        {
            return TypedResults.BadRequest("Invalid model");
        }
        if(!backgroundTranslateService.TranslationServiceUp)
        {
            return TypedResults.BadRequest("Translation service is down");
        }
        // Create a unique identifier for this translation task
        var taskId = Guid.NewGuid().ToString("N");
        var userId = Request.GetUserId(Response);
       
        // Trigger translation and store the associated task
        var translationTask = await backgroundTranslateService.Translate(model);
    
        var translateTask = new TranslateTask(taskId, DateTime.Now,  model.Language, translationTask);
        translateCacheService.AddTask(userId, translateTask);

        // Return the task ID to the client
        return TypedResults.Ok(taskId);
    }

अनुवाद प्राप्त करने का अंतिम बिन्दु

यह HTMX का उपयोग करके अनुरोध किया जाता है और मौजूदा उपयोक्ता के लिए अनुवादों को वापस करता है

    [HttpGet]
    [Route("get-translations")]
    public IActionResult GetTranslations()
    {
        var userId = Request.GetUserId(Response);
        var tasks = translateCacheService.GetTasks(userId);
        var translations = tasks.Select(x=> new TranslateResultTask(x, false)).ToList();
        return PartialView("_GetTranslations", translations);
    }
    

अनुवाद आंशिक दृश्य प्राप्त करें

यह एक सरल दृश्य है जो HTMX का उपयोग कर सर्वर को हर 5 सेकंड पर मतदान करता है ताकि मौजूदा उपयोक्ता के लिए अनुवाद प्राप्त किया जा सके

यह भी है जब सभी अनुवाद पूर्ण कर रहे हैं के लिए संचालन मतदान ( सेटिंग ट्रिगर को बंद करने के लिए noneऔर एक वैकल्पिक संदेश प्रदर्शित करने के लिए जब कोई अनुवाद नहीं हैं

मैं मानवizer लाइब्रेरी का उपयोग भी मानवीय पठनीय ढाँचा में अनुवाद को पूरा करने के लिए लगने वाले समय को दिखाने के लिए करता हूँ

यह इस दृश्य में परिणाम करता है

अनुवाद

@using Humanizer
@using Mostlylucid.Helpers
@model List<Mostlylucid.MarkdownTranslator.Models.TranslateResultTask>

@{
    var allCompleted = Model.All(x => x.Completed);
    var noTranslations = Model.Count == 0;
    var trigger = allCompleted ? "none" : "every 5s";
    if (noTranslations)
    {
        <div class="alert alert-info" role="alert">
            No translations have been requested yet.
        </div>
    }
    else
    {
        <div class="translationpoller" hx-controller="Editor" hx-action="GetTranslations" hx-get hx-swap="outerHTML" hx-trigger="@trigger">
            <table class="table">
                <thead>
                <th>
                  
                    @Html.DisplayNameFor(model => model[0].TaskId)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model[0].Completed)
                </th>
                <th >
                    @Html.DisplayNameFor(model => model[0].Language)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model[0].TotalMilliseconds)
                </th>
                </thead>
                @foreach (var item in Model)
                {
                    <tr>
                        <td>  <a href="#" x-on:click.prevent="window.mostlylucid.translations.viewTranslation('@item.TaskId')">View</a></td>
                        <td>@if (item.Completed)
                            {
                                <i class='bx bx-check text-green'></i>
                            }
                            else
                            {
                                <i class='bx bx-loader-alt animate-spin dark:text-white text-black'></i>
                            }
                            </td>
                        <td>
                            <p class="flex items-center">
                                <img src="/img/flags/@(item.Language).svg" asp-append-version="true" class="ml-2 h-4 w-4 mr-4 rounded outline outline-1 outline-green-dark dark:outline-white" alt="@item.Language">
                                @item.Language.ConvertCodeToLanguage()
                            </p>

                        </td>
                        <td>@(TimeSpan.FromMilliseconds(item.TotalMilliseconds).Humanize())</td>
                    </tr>
                }
            </table>
        </div>
    }
}

दृश्य अनुवाद फ़ंक्शन

जैसा कि आप ऊपर की दृश्य में देखेंगे हम एक छोटा अल्पिंग पर क्लिक करने के लिए अनुवाद देखने को बुलाते हैं

 <a href="#" x-on:click.prevent="window.mostlylucid.translations.viewTranslation('@item.TaskId')">View</a>

जो इस में कॉल करता है


export function viewTranslation(taskId) {
    // Construct the URL with the query parameters
    const url = `/api/translate/get-translation/${taskId}`;

    // Fetch call to the API endpoint
    fetch(url, {
        method: 'GET',
        headers: {
            'Accept': 'application/json'  // Indicate that we expect a JSON response
        }
    })
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error! Status: ${response.status}`);
            }
            return response.json();
        })
        .then(data =>

        {
            let translatedContentArea = document.getElementById("translatedcontent")
            translatedContentArea.classList.remove("hidden");
            let textArea = document.getElementById('translatedcontentarea');
            textArea.classList.remove('hidden');
            textArea.value = data.originalMarkdown;
            simplemde.value(data.translatedMarkdown);
        })  // Log the successful response data
        .catch(error => console.error('Error:', error));  // Handle any errors
}

अनुवाद अंतबिन्दु प्राप्त करें

यह अनुवादों की सूची प्राप्त करने के लिए पहले विधि के समान है सिवाय इसके कि यह एक एकल अनुवाद के साथ प्राप्त करता है OriginalMarkdown और TranslatedMarkdown populated:

    [HttpGet]
    [Route("get-translation/{taskId}")]
    public Results<JsonHttpResult<TranslateResultTask>, BadRequest<string>> GetTranslation(string taskId)
    {
        var userId = Request.GetUserId(Response);
        var tasks = translateCacheService.GetTasks(userId);
        var translationTask = tasks.FirstOrDefault(t => t.TaskId == taskId);
        if (translationTask == null) return TypedResults.BadRequest("Task not found");
        var result = new TranslateResultTask(translationTask, true);
        return TypedResults.Json(result);
    }

अंत में

इस सब का परिणाम यह है कि आप अब अनुवाद अनुरोध प्रस्तुत कर सकते हैं और इसके बाद संपादक में अनुवाद की स्थिति देख सकते हैं।

मैं यहाँ कुछ और करना चाहता हूँ जिसमें पुनः- अनुवादित सामग्री आदि के लिए रेंडर मार्कडाउन प्रवाह को खींचना है। फिर से, आप अपने पर इस के लिए सभी स्रोत कोड देख सकते हैं जिटहब पृष्ठ. तो अगर आप अधिक देखने के लिए जाना चाहते हैं तो कृपया उस पर देखो

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.