Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Trang web đa ngôn ngữ thực hành tốt nhất

Tiền đề của chủ đề

Có ba khía cạnh khác biệt trong một trang web đa ngôn ngữ:

  • bản dịch giao diện
  • nội dung
  • định tuyến url

Mặc dù tất cả chúng được kết nối với nhau theo những cách khác nhau, nhưng theo quan điểm của CMS, chúng được quản lý bằng cách sử dụng các phần tử giao diện người dùng khác nhau và được lưu trữ theo cách khác nhau. Bạn có vẻ tự tin vào khả năng thực hiện và hiểu biết của mình về hai điều đầu tiên. Câu hỏi là về khía cạnh thứ hai - "Dịch URL? Chúng ta có nên làm điều này hay không? Và theo cách nào?"

URL có thể được làm bằng gì?

Một điều rất quan trọng là đừng quá ưa thích IDN . Thay vào đó, hãy ưu tiên chuyển ngữ (còn:phiên âm và chữ La tinh). Mặc dù thoạt nhìn IDN có vẻ là lựa chọn khả thi cho các URL quốc tế, nhưng thực tế nó không hoạt động như được quảng cáo vì hai lý do:

  • một số trình duyệt sẽ chuyển các ký tự không phải ASCII như 'ч' hoặc 'ž' thành '%D1%87''%C5%BE'
  • nếu người dùng có chủ đề tùy chỉnh, phông chữ của chủ đề rất có thể không có ký hiệu cho các chữ cái đó

Tôi thực sự đã cố gắng tiếp cận IDN vài năm trước trong một dự án dựa trên Yii (khuôn khổ khủng khiếp, IMHO). Tôi gặp phải cả hai vấn đề được đề cập ở trên trước khi loại bỏ giải pháp đó. Ngoài ra, tôi nghi ngờ rằng nó có thể là một vectơ tấn công.

Các tùy chọn có sẵn ... như tôi thấy.

Về cơ bản, bạn có hai lựa chọn, có thể được tóm tắt là:

  • http://site.tld/[:query] :where [:query] xác định cả lựa chọn ngôn ngữ và nội dung

  • http://site.tld/[:language]/[:query] :where [:language] một phần của URL xác định lựa chọn ngôn ngữ và [:query] chỉ được sử dụng để xác định nội dung

Truy vấn là Α và Ω ..

Giả sử bạn chọn http://site.tld/[:query] .

Trong trường hợp đó, bạn có một nguồn ngôn ngữ chính:nội dung của [:query] bộ phận; và hai nguồn bổ sung:

  • giá trị $_COOKIE['lang'] cho trình duyệt cụ thể đó
  • danh sách các ngôn ngữ trong tiêu đề Ngôn ngữ chấp nhận HTTP

Trước tiên, bạn cần đối sánh truy vấn với một trong các mẫu định tuyến đã xác định (nếu lựa chọn của bạn là Laravel, thì hãy đọc ở đây ). Khi đối sánh thành công mẫu, bạn cần tìm ngôn ngữ.

Bạn sẽ phải đi qua tất cả các phân đoạn của mẫu. Tìm các bản dịch tiềm năng cho tất cả các phân đoạn đó và xác định ngôn ngữ nào đã được sử dụng. Hai nguồn bổ sung (cookie và tiêu đề) sẽ được sử dụng để giải quyết xung đột định tuyến, khi (không phải "nếu") chúng phát sinh.

Lấy ví dụ:http://site.tld/blog/novinka .

Đó là phiên âm của "блог, новинка" , trong tiếng Anh có nghĩa là khoảng "blog", "latest" .

Như bạn đã có thể nhận thấy, trong tiếng Nga, "блог" sẽ được chuyển ngữ thành "blog". Điều đó có nghĩa là đối với phần đầu tiên của [:query] bạn (trong trường hợp tốt nhất ) sẽ kết thúc bằng ['en', 'ru'] danh sách các ngôn ngữ có thể. Sau đó, bạn thực hiện phân đoạn tiếp theo - "novinka". Ngôn ngữ đó có thể chỉ có một ngôn ngữ trong danh sách các khả năng:['ru'] .

Khi danh sách có một mục, bạn đã tìm thấy ngôn ngữ thành công.

Nhưng nếu bạn có 2 khả năng (ví dụ:tiếng Nga và tiếng Ukraina) trở lên .. hoặc 0 khả năng, tùy từng trường hợp. Bạn sẽ phải sử dụng cookie và / hoặc tiêu đề để tìm tùy chọn chính xác.

Và nếu vẫn thất bại, bạn chọn ngôn ngữ mặc định của trang web.

Ngôn ngữ làm tham số

Cách thay thế là sử dụng URL, có thể được định nghĩa là http://site.tld/[:language]/[:query] . Trong trường hợp này, khi dịch truy vấn, bạn không cần phải đoán ngôn ngữ, vì tại thời điểm đó, bạn đã biết phải sử dụng ngôn ngữ nào.

Ngoài ra còn có một nguồn ngôn ngữ phụ:giá trị cookie. Nhưng ở đây không có ý nghĩa gì với tiêu đề Chấp nhận ngôn ngữ, bởi vì bạn không xử lý số lượng ngôn ngữ không xác định có thể có trong trường hợp "khởi động lạnh" (khi người dùng lần đầu tiên mở trang web với truy vấn tùy chỉnh).

Thay vào đó, bạn có 3 tùy chọn đơn giản, được ưu tiên:

  1. if [:language] phân đoạn đã được thiết lập, hãy sử dụng nó
  2. if $_COOKIE['lang'] được thiết lập, hãy sử dụng nó
  3. sử dụng ngôn ngữ mặc định

Khi bạn có ngôn ngữ, bạn chỉ cần cố gắng dịch truy vấn và nếu dịch không thành công, hãy sử dụng "giá trị mặc định" cho phân đoạn cụ thể đó (dựa trên kết quả định tuyến).

Đây không phải là lựa chọn thứ ba?

Có, về mặt kỹ thuật, bạn có thể kết hợp cả hai phương pháp, nhưng điều đó sẽ làm phức tạp quy trình và chỉ phù hợp với những người muốn thay đổi thủ công URL của http://site.tld/en/news tới http://site.tld/de/news và mong đợi trang tin tức chuyển sang tiếng Đức.

Nhưng ngay cả trường hợp này cũng có thể được giảm thiểu bằng cách sử dụng giá trị cookie (sẽ chứa thông tin về lựa chọn ngôn ngữ trước đó), để triển khai với ít ma thuật và hy vọng hơn.

Sử dụng cách tiếp cận nào?

Như bạn có thể đã đoán, tôi khuyên bạn nên sử dụng http://site.tld/[:language]/[:query] là tùy chọn hợp lý hơn.

Ngoài ra trong tình huống từ thực tế, bạn sẽ có phần chính thứ 3 trong URL:"tiêu đề". Như tên của sản phẩm trong cửa hàng trực tuyến hoặc tiêu đề của bài báo trên trang web tin tức.

Ví dụ:http://site.tld/en/news/article/121415/EU-as-global-reserve-currency

Trong trường hợp này '/news/article/121415' sẽ là truy vấn và 'EU-as-global-reserve-currency' là tiêu đề. Hoàn toàn cho mục đích SEO.

Nó có thể được thực hiện trong Laravel không?

Kinda, nhưng không phải theo mặc định.

Tôi không quá quen thuộc với nó, nhưng từ những gì tôi đã thấy, Laravel sử dụng cơ chế định tuyến dựa trên mẫu đơn giản. Để triển khai các URL đa ngôn ngữ, bạn có thể phải mở rộng (các) lớp lõi , bởi vì định tuyến đa ngôn ngữ cần quyền truy cập vào các dạng lưu trữ khác nhau (cơ sở dữ liệu, bộ nhớ cache và / hoặc tệp cấu hình).

Nó đã được định tuyến. Làm gì bây giờ?

Kết quả của tất cả, bạn sẽ nhận được hai phần thông tin có giá trị:ngôn ngữ hiện tại và các phân đoạn truy vấn đã dịch. Sau đó, các giá trị này có thể được sử dụng để gửi đến (các) lớp sẽ tạo ra kết quả.

Về cơ bản, URL sau:http://site.tld/ru/blog/novinka (hoặc phiên bản không có '/ru' ) bị biến thành một thứ gì đó giống như

$parameters = [
   'language' => 'ru',
   'classname' => 'blog',
   'method' => 'latest',
];

Cái mà bạn chỉ sử dụng để gửi:

$instance = new {$parameter['classname']};
$instance->{'get'.$parameters['method']}( $parameters );

.. hoặc một số biến thể của nó, tùy thuộc vào cách triển khai cụ thể.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sao lưu các phương pháp hay nhất cho MySQL, MariaDB và Galera Cluster

  2. Làm thế nào để "Unhex" một số trong MySQL

  3. Trong các truy vấn MySQL, tại sao lại sử dụng join thay vì ở đâu?

  4. Cài đặt Ruby gem mysql2 không thành công

  5. Đối chiếu phân biệt chữ hoa chữ thường trong MySQL