برنامه نویسی

ترجمه اپلیکیشن وب به دو صورت.

در این مقاله، من به شما نشان خواهم داد که چگونه یک برنامه وب ساخته شده با استفاده از ASP.NET را ترجمه کنید و دو روش پیاده سازی را مورد بحث قرار دهیم. اولین روشی که در شناخت آن مهارت دارید از منابع ثابت استفاده می کند. روش دوم از API شخص ثالث استفاده می کند. ما تمام جوانب مثبت و منفی هر تکنیک را در نظر خواهیم گرفت. و مطمئنا، ما در حال نوشتن کد خواهیم بود.

ترجمه با استفاده از منابع ثابت

این روش به طور گسترده مورد استفاده قرار می گیرد و اغلب در پروژه های مختلف اجرا می شود. شما به هیچ بسته یا API شخص ثالث نیاز ندارید. ابتدا، را اصلاح کنید Program.cs فایل و فرهنگ های پشتیبانی شده را اضافه کنید. فقط این ردیف ها را اضافه کنید.

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

var supportedCultures = new[]
{
    new CultureInfo("en-US"),
    new CultureInfo("fr-FR")
};

builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("en-US");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
});

builder.Services.AddControllersWithViews()
    .AddViewLocalization()
    .AddDataAnnotationsLocalization();

var locOptions = app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از آنجایی که ما دو طرح بندی را ترجمه خواهیم کرد، باید پوشه ها را ایجاد کنیم. سلسله مراتب پوشه ها باید مانند پروژه باشد. لطفاً پوشه منابع و پوشه های مشتق شده را همانطور که در تصویر نشان داده شده است ایجاد کنید.

آیفولدرها

در هر پوشه، یک فایل منبع ایجاد کنید و ترجمه مورد نیاز را اضافه کنید.

منابع

برای عملی بودن بیشتر، یک منوی کشویی برای زبان‌های انتخابی اضافه می‌کنم. برو به _Layout.cshtml و این کد را اضافه کنید

asp-controller="Home" asp-action="SetLanguage" method="post">
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای حفظ وضعیت باید کوکی ها را ذخیره کنیم. سپس پس از رفرش صفحه، زبان انتخابی شما حفظ خواهد شد. برو به HomeController و روش POST را برای مدیریت کوکی ها اضافه کنید.

[HttpPost]
    public IActionResult SetLanguage(string culture, string? returnUrl)
    {
        Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
            new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
        );

        return LocalRedirect(returnUrl ?? "https://dev.to/");
    }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در آخرین مراحل، باید طرح‌بندی‌ها را تغییر دهید و متنی را که می‌خواهید ترجمه کنید جایگزین کنید. برو به Index.cshtml فایل

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
    ViewData["Title"] = "Home Page";
}

class="text-center"> @Localizer["LearnMore"]
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همچنین، به _Layout.cshtml را فایل کنید و لیست منوی پیمایش و پاورقی را تغییر دهید.



class="border-top footer text-muted">
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بیایید این را بررسی کنیم. محلی سازی پیش فرض به نظر می رسد.

در

در صورت تغییر زبان، صفحه ترجمه شده به فرهنگ مورد نظر را خواهید دید.

fr

اگر صفحه را بازخوانی کنید، همچنان بومی سازی فرانسوی را خواهد داشت. اگر برنامه را دوباره راه اندازی کنید، همچنان ترجمه فرانسوی را خواهید دید. مرورگر شما فرهنگ انتخابی را در کوکی ها نگه می دارد.

حال بیایید مزایا و معایب این روش را در نظر بگیریم.

جوانب مثبت

  • سادگی
  • بدون نیاز به بسته های دیگر
  • به طور گسترده استفاده می شود
  • کاملا رایگان

منفی

  • شما نیاز به ترجمه مستقل دارید
  • میتونی ترجمه کنی اشتباهه
  • متن باید با دست تایپ شود
  • تست کردن دشوار است
  • سخت برای نگهداری

ترجمه با استفاده از بسته شخص ثالث

این رویکرد شامل استفاده از API شخص ثالث است. من سرویسی به نام DeepL پیاده سازی کرده ام که می تواند متن HTML را پردازش کند. برای ثبت نام به آدرس https://www.deepl.com/ مراجعه کنید. این سرویس به شما امکان می دهد تا 500000 کاراکتر را بدون پرداخت هزینه ترجمه کنید.

برنامه ریزی کنید

برای ثبت نام و ایجاد اشتراک باید یک کارت اعتباری معتبر اضافه کنید.

فرم ثبت نام

وقتی این کار را انجام دادید، به نمایه خود بروید.

نمایه

سپس به تب API keys رفته و کلید API را کپی کنید.

کلید API

حالا بیایید کد بنویسیم. شما همچنین باید اصلاح کنید Program.cs، اما می توانید آن را از پروژه قبلی کپی کنید.

این رویکرد بهترین است زیرا به جز در برخی موارد نیازی به اصلاح طرح‌بندی ندارد. ما فقط یک کشویی مانند نمونه قبلی اضافه می کنیم.

باید اصلاح دیگری انجام دهید. DeepL می تواند به اشتباه کاراکترهای خاص مانند علائم حق چاپ را کنترل کند. با بسته بندی ظرف DIV حل می شود. DeepL سعی می کند کد کاراکتر ویژه را ترجمه کند. برای این مورد، API ویژگی و کلاس خاصی را ارائه کرد که در آن می توانید ترجمه را ممنوع کنید. در ظرف DIV به درستی کار خواهد کرد. مسئله دیگر این است که نام عمل ASP باید با مقدار متفاوت باشد. در غیر این صورت ترجمه نمی شود. به همین دلیل است که من مقدار را از Privacy به Policy تغییر دادم. تغییر یک مقدار آسان‌تر از انجام آن با یک اقدام ASP است.

class="border-top footer text-muted">
class="container grid-container">

class="notranslate" translate="no">©

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بدون استایل زیبا به نظر نمی رسد. شما باید بلوک های درون خطی بسازید.
استایل ها را برای ظرف اضافه کنید.

.grid-container {
  display: grid;
  grid-template-columns: auto auto;
  grid-gap: 5px;
  width: fit-content;
  white-space: nowrap;
} 
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

از آنجایی که ما از مکانیسم مشابهی برای تغییر زبان استفاده می کنیم، باید آن را اضافه کنید SetLanguage() روش به HomeController که در نمونه قبلی استفاده کردیم.

قبل از اجرای منطق ترجمه، باید دو بسته را نصب کنیم.
این بسته برای ترجمه مورد نیاز است:

dotnet add package DeepL.net --version 1.11.0
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این بسته برای مدیریت اسناد HTML مورد نیاز است:

dotnet add package HtmlAgilityPack --version 1.11.71
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

پس از انجام آن، لطفاً روش موجود خود را اصلاح کنید، Index(), در HomeController. توضیح می دهم آنجا چه خبر است.

public async Task<IActionResult> Index()
    {
        var currentCulture = CultureInfo.CurrentCulture.Name;
        var sourceLanguage = "en";
        string targetLanguage;

        var htmlContent = await RenderViewToStringAsync("Index");
        switch (currentCulture)
        {
            case "en-US":
                return Content(htmlContent, "text/html");
            case "fr-FR":
                targetLanguage = "fr";
                break;
            default:
                return BadRequest("Unsupported language.");
        }

        var nodes = ExtractNodes(htmlContent);

        var cacheKey = string.Join("_", nodes) + $"_{sourceLanguage}_{targetLanguage}";

        if (!cache.TryGetValue(cacheKey, out string[]? texts))
        {
            var translator = new Translator("YourApiKey");
            var text = await translator.TranslateTextAsync(nodes, sourceLanguage, targetLanguage);
            texts = text.Select(x => x.Text).ToArray();

            var cacheOptions = new MemoryCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
            };
            cache.Set(cacheKey, texts, cacheOptions);
        }

        for (var i = 0; i < nodes.Length; i++)
        {
            var oldNode = nodes.ElementAt(i);
            if (texts == null) continue;
            var newNode = texts.ElementAt(i);
            htmlContent = htmlContent.Replace(oldNode, newNode);
        }

        return Content(htmlContent, "text/html");
    }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اما روش دیگری را اضافه کنید که به آن فراخوانی می کنیم Index() روش

private async Task RenderViewToStringAsync(string viewName)
{
    await using var writer = new StringWriter();
    var viewResult = viewEngine.FindView(ControllerContext, viewName, isMainPage: true);
    if (!viewResult.Success)
    {
        throw new FileNotFoundException($"View {viewName} not found");
    }

    ViewData["Title"] = "Home Page";

    var viewContext = new ViewContext(
        ControllerContext,
        viewResult.View,
        ViewData,
        TempData,
        writer,
        new HtmlHelperOptions()
    );

    await viewResult.View.RenderAsync(viewContext);
    return writer.ToString();
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این روش برای تجزیه کد HTML و برگرداندن آن به عنوان یک رشته مورد نیاز است. حالا به متد Index() برگردیم. وقتی HTML را تجزیه کردیم، فرهنگ فعلی را بررسی کردیم. اگر فرهنگ EN باشد، کاری انجام نمی دهیم و محتوای HTML اصلاح نشده را برمی گردانیم. ما نیازی به ترجمه به انگلیسی نداریم زیرا این زبان به طور پیش فرض استفاده می شود. اگر فرهنگ FR باشد، زبان مقصد را تعیین می کنیم. حالا باید روش دیگری اضافه کنید:

private static string[] ExtractNodes(string htmlContent)
    {
        var nodes = new List<string>();
        var tags = new[] { "//title", "//ul", "//h1", "//p", "//footer" };

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(htmlContent);

        foreach (var tag in tags)
        {
            var node = htmlDoc.DocumentNode.SelectSingleNode(tag);
            if (node.InnerHtml != null)
            {
                nodes.Add(node.InnerHtml);
            }
        }

        return nodes.ToArray();
    }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این روش بلوک های مشخص شده کد HTML را استخراج می کند. مانند یک فیلتر عمل می کند. به عنوان مثال، اگر ما را اعلام کنیم //ul تگ کنید، سپس متد محتویات این بلوک را برمی گرداند. این روش برای ترافیک با استفاده ناب مورد نیاز است. از آنجایی که DeepL دارای محدودیت هایی برای کاراکترها است، باید استفاده از کاراکترها را کاهش دهیم و فقط بلوک های مورد نیاز را ترجمه کنیم.

یکی دیگر از بهینه‌سازی‌ها، حافظه پنهان است. وقتی صفحه ترجمه شد، دیگر نیازی به ترجمه آن نداشتیم. در صورت تمایل می توانید از یک ارائه دهنده کش دیگر استفاده کنید. اگر کش خالی است، باید کد استخراج شده را ترجمه کنید. شما باید از کلید API که قبلاً دریافت کرده اید استفاده کنید. به محض دریافت کد HTML ترجمه شده، باید کد را در سند اصلی HTML جایگزین کنید.

بیایید این را بررسی کنیم.

در نسخه

نسخه fr

حال بیایید مزایا و معایب این راه را در نظر بگیریم.

جوانب مثبت

  • بدون نیاز به ایجاد منابع با دست
  • ترجمه هوش مصنوعی
  • نیازی به نگهداری هر ترجمه نیست
  • بدون نیاز به جایگزینی مقادیر با دست در طرح‌بندی‌ها
  • آسان برای تست
  • در وقت شما صرفه جویی می کند

منفی

  • اجرای پیچیده تر
  • اشتراک مورد نیاز
  • اشتراک رایگان محدودیت هایی دارد
  • تعداد محدودی از زبان ها
  • مشکلاتی با کاراکترهای خاص و عملکردهای ASP دارند

نتیجه گیری

ترجمه را به دو صورت اجرا کردم. مورد اول بیشتر مورد استفاده قرار می گیرد زیرا ساده تر و کاملا رایگان است. گزینه دوم یک نقل قول رایگان ارائه می دهد، اما برای ترجمه تمام صفحات وب بدون پرداخت کافی نیست. زمان یک مهندس نرم افزار گران تر از هزینه اشتراک خدمات ترجمه است.

کد منبع توسط لینک.

امیدوارم این مقاله برای شما مفید بوده باشد و دفعه بعد شما را ببینم. کد نویسی مبارک!

برای من آبجو بخر

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا