Invenzzia »

Pages: [1]   Go Down
  Print  
Author Topic: OPTv2: Znak   zamieniany na krzaczki.  (Read 4730 times)
0 Members and 2 Guests are viewing this topic.
mrKrecik
User

Offline Offline

Posts: 3


View Profile
« on: September 18, 2009, 00:36:34 »

Witam,

W szablonie stosuję znak  , niestety, po kompilacji jest on zamieniany na "� ". Próbowałem zamieniać z XHTML na HTML, wyłączałem kompresję, bawiłem się wszelkimi opcjami, ale niestety - bez efektów.

pozdrawiam i z góry dziękuję za pomoc
mrKrecik
Logged
Zyx
Your programmer
Administrator
User
*****
Offline Offline

Posts: 291



View Profile WWW
« Reply #1 on: September 18, 2009, 07:12:57 »

Jakiego kodowania i wersji PHP używasz? Jeśli występuje u Ciebie błąd z dekodowaniem encji, oznacza to raczej problem ze źle obsługującą Unikod przeglądarką, albo PHP, gdyż OPT używa do tego celu ogólnodostępnej funkcji html_entity_decode(). Sprawdziłem przed chwilą u siebie - zarówno na kodowaniu UTF-8, jak i ISO-8859-1, otrzymuję prawidłowo niełamalną spację.
Logged

PozDrX, Zyx
---Invenzzia group---
mrKrecik
User

Offline Offline

Posts: 3


View Profile
« Reply #2 on: September 18, 2009, 11:40:22 »

Problem powstaje na dwóch różnych serwerach:

1) Apache 2.2.6 PHP 5.2.5
2) Apache 2.2.5 PHP 5.2.9

Sprawdzałem pod przeglądarką FF 3.5.3 i IE8.

TPL:
Code:
<opt:root>
<opt:dtd template="xhtml10transitional" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl">
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="pl" />
    <link rel="stylesheet" type="text/css" parse:href="$strBaseUrl~'assets/css/pa_style.css'" />
    <script type="text/javascript" parse:src="$strBaseUrl~'assets/js/script.js'"></script>
  </head>
  <body>&nbsp;</body>
</html>
</opt:root>

OPT_CLASS:
Code:
$this -> opt_class = new Opt_Class;
$this -> opt_class -> sourceDir = $strDir . 'views/';
$this -> opt_class -> compileDir = $strDir . 'views_c/';
$this -> opt_class -> contentType = Opt_Output_Http::XHTML;
$this -> opt_class -> charset = 'utf-8';
$this -> opt_class -> gzipCompression = False;
$this -> opt_class -> setup();

OUTPUT:
Code:
$this -> output -> setContentType();
$this -> output -> render( $this -> view );

Próbowałem debuggować coś i okazało się, że w pliku Compiler/Class.php w linijce 2098 "&nbsp;" jest zmienione na spację, a preg_replace, który znajduje się w tej linijce tworzy z niej ten dziwny znak. Wówczas pomyślałem, że &nbsp; jest źle zmienione na spacje (wprawdzie sam nie wiem jak to możliwe), ale była to 5 rano, więc nie miałem już siły szukać w którym miejscu cała klasa zmienia "&nbsp;" na spację.

pozdrawiam
mrKrecik
Logged
Zyx
Your programmer
Administrator
User
*****
Offline Offline

Posts: 291



View Profile WWW
« Reply #3 on: September 18, 2009, 15:39:04 »

Uruchomiłem Twój szablon na takich ustawieniach, jakie podajesz i kompilator prawidłowo zamienił encję. Skłaniam się ku temu, że OPT dostaje już walnięty szablon do przetworzenia. Mogę podać Ci miejsca, które możesz dodatkowo sprawdzić, gdyż - jak widzisz - ja nie mam takiej możliwości, jako że mi zarówno unit testy, jak i podany przez Ciebie kod generują poprawny wynik.

Encje są zamieniane w Opt_Compiler_Class::_treeTextCompile() poprzez wywołanie metody _parseEntities(). Ta wyrażeniem regularnym wyszukuje w podanym ciągu encje i przekazuje je do prywatnej metody _decodeEntity() odpowiedzialnej za ich zamianę na odpowiednie znaki. Jeśli pierwsza z podanych metod dostaje już tekst z zamienioną encją, przyjrzyj się metodzie _stage1(). Jeśli i ona dostaje tekst z już podmienioną encją, to oznacza, że plik w błędnej postaci jest wczytywany już z dysku twardego.
Logged

PozDrX, Zyx
---Invenzzia group---
mrKrecik
User

Offline Offline

Posts: 3


View Profile
« Reply #4 on: September 18, 2009, 22:42:12 »

Sprawdziłem dzisiaj jeszcze raz wszystko dokładnie.
W ASCII znak "&nbsp; ma numer #160.

Gdy znak ten wchodzi w html_entity_decode() (linia 3613) to jest zmieniany na ASCII 194. Dalej znak zmieniany jest przez preg_replace() (linia 2098) na ten dziwny krzak.

Kod który to pokazuje dokładnie (u mnie po włączeniu pokazuje się krzak):
Code:
<?php

$strString 
'&nbsp;';

$strStringhtml_entity_decode$strStringENT_COMPAT'utf-8' );

echo 
preg_replace'/(\s){1,}/'' ', (string)$strString );

?>

Gdy natomiast wywalę z html_entity_decode() 'utf-8' to całość zaczyna działać poprawnie. Tzn. znak &nbsp; zamieniany jest na ASCII 160 i dalej już wszystko jest ok.

Sam nie wiem czemu tak się dzieje... :|

pozdrawiam
mrKrecik

Edit:
Uruchamiając powyższy kod na innym serwerze wszystko działa poprawnie. Jednakże gdy uruchamiam cały projekt to krzaki dalej wyskakują... :|

Edit2:
Problem zniknął. Po części wynikał z mojego pośpiechu. Kopiując pliki na serwer odpalałem skrypt, a ten brał szablony z cache. Natomiast w cache były skompilowane na moim serwerze szablony, więc zawierały te dziwne krzaki. Wina ewidentnie leży po stronie mojego serwera, a czemu to już się pewnie nie dowiem. :)
« Last Edit: September 18, 2009, 23:22:00 by mrKrecik » Logged
Zyx
Your programmer
Administrator
User
*****
Offline Offline

Posts: 291



View Profile WWW
« Reply #5 on: September 19, 2009, 07:08:19 »

Tak przypuszczałem, choć też nie mam pojęcia, co to za dziwaczny serwer... jeśli bez html_entity_decode() masz już encje zamienione na właściwe znaki, to ewidentnie jest coś z serwerem. Encje same z siebie się nie zamienią. Jak do zmiennej zapiszesz ciąg '&nbsp;' to powinien on zawierać dokładnie 6 znaków ASCII:

Code:
&
n
b
s
p
;
Logged

PozDrX, Zyx
---Invenzzia group---
zaksmok
User

Offline Offline

Posts: 12


View Profile
« Reply #6 on: August 30, 2010, 10:11:47 »

Witam, odświeżam temat &nbsp;. Niestety, ale po 3 dniach walki nie potrafię rozgryźć problemu.
http://expo.vel.pl/pl/drukarnia/o-firmie - wynik

Konfiguracja na utf-8, szablony są zapisywane w utf-8
Code:
$objOpt->charset = 'utf-8';
$objOpt->setup();

Please help me... A swoją drogą czy skompilowane pliki mogą być zapisywane do utf-8? czy to musi być ANSI?
« Last Edit: August 30, 2010, 15:59:54 by zaksmok » Logged
Zyx
Your programmer
Administrator
User
*****
Offline Offline

Posts: 291



View Profile WWW
« Reply #7 on: August 30, 2010, 13:15:29 »

Ad. 1 - problem czcionki albo zepsutego kodowania Unicode na Twojej stronie, a nie OPT. Czy wywołujesz następującą linijkę?

Code:
$output = Opt_Output_Http;
$output->setContentType();

Metoda setup() nie wysyła do przeglądarki żadnych informacji o kodowaniu. Ponadto jeśli zależy Ci na tym, by przeglądarka widziała encję, możesz skorzystać z następującej funkcji:

http://static.invenzzia.org/docs/opt/2_0/book/en/syntax.functions.entity.html

Ad. 2 - UTF-8 jest zmodyfikowanym ANSI. Open Power Template nie robi nic z kodowaniem - jak sobie zapiszesz szablon źródłowy w UTF-8, to skompilowany też będziesz mieć w UTF-8.
Logged

PozDrX, Zyx
---Invenzzia group---
zaksmok
User

Offline Offline

Posts: 12


View Profile
« Reply #8 on: August 30, 2010, 15:57:41 »

OPT kompiluję poprzez  Opt_Output_Return, na początku skryptu
Code:
header('Content-Type: text/html; charset=UTF-8');

Żeby było śmieszniej to niektóre szablony zapisane w UTF-8 są generowane do ANSI
« Last Edit: August 30, 2010, 16:00:16 by zaksmok » Logged
Zyx
Your programmer
Administrator
User
*****
Offline Offline

Posts: 291



View Profile WWW
« Reply #9 on: August 30, 2010, 20:20:08 »

Quote
Żeby było śmieszniej to niektóre szablony zapisane w UTF-8 są generowane do ANSI

OPT nie zmienia kodowania plików. Błąd musi leżeć w Twoim kodzie, bo jak wytłumaczysz to, że na 1000 innych stron to jakoś działa bez większych problemów? Zresztą, jeśli dalej twierdzisz, że jest inaczej, to spróbuj znaleźć w kodzie wywołanie jakiejkolwiek funkcji zmieniającej kodowanie. Spróbowałem zreprodukować nawet Twój problem i nie udało mi się. Encje są poprawnie zamieniane, a kodowanie zostaje po staremu.

Przesłankę do tego, że gdzieś coś namieszałeś, widzę i w Twoim poście (dlaczego generujesz wynik przez Opt_Output_Return, kiedy jest Opt_Output_Http?), jak i w kodzie HTML strony, bowiem na jej końcu mogę znaleźć:

Quote
<div id="debug" style="background: #eee; padding: 5px; font-size: 10px; color: #000; margin-top: 20px">
   <b>Debug machine</b><br/>
   Executing time: <br />
<b>Fatal error</b>:  Call to undefined function xdebug_time_index() in <b>.../tf/expo/html/core.php</b> on line <b>31</b><br />
Logged

PozDrX, Zyx
---Invenzzia group---
Kozack
User

Offline Offline

Posts: 5


View Profile
« Reply #10 on: October 29, 2010, 22:44:02 »

Widzę, że problem nie został do końca rozwiązany, a ostatnio trafiłem na coś podobnego, więc odświeżam temat.

Encje &nbsp; są dekodowane poprawnie, ale krzaki pojawiają się tylko przy włączonym "stripWhitespaces".

Encje dekodowane są w Opt_Compiler_Class::_decodeEntity (linia 3655). Encje dekodowane są poprawnie. Dla kodowania UTF-8 &nbsp; jest zamieniane na c2 a0 (c2 to #194), a przy ISO-8859-2 na a0 (#160).

Następnie w Opt_Compiler_Class::_stage3 (linia 2114) wyrażenie regularne zamienia wszystkie ciągi białych znaków na pojedyncze spacje. W tym momencie nasze c2 a0 jest zamieniane na c2 (stąd znak o kodzie #194) i krzak na stronie.

Jeżeli poprawimy wyrażenie regularne z:

Code:
$output .= $this->parseSpecialChars(preg_replace('/(\s){1,}/', ' ', (string)$item));

na:

Code:
$output .= $this->parseSpecialChars(preg_replace('/(\s){1,}/u', ' ', (string)$item));

To wszystko działa poprawnie (spacje "nbsp" są usuwane i nie ma krzaków).

Pytania:

a) Czy wyrażenie regularne jest poprawne (przykład powyżej)?

b) Czy włączenie kompresji HTML-a powinno kasować również spacje "nbsp"? Skoro wstawiamy "nbsp", to znaczy, że chcemy, aby w tym miejscu była dodatkowa spacja. Uważam, że "stripWhitespaces" nie powinno jej kasować.

c) Jest inne rozwiązanie oprócz używania funkcji "entity" w szablonie?
Logged
Zyx
Your programmer
Administrator
User
*****
Offline Offline

Posts: 291



View Profile WWW
« Reply #11 on: October 31, 2010, 23:22:17 »

No widzisz, to jest naprawdę porządna analiza, która umożliwia mi rozwiązanie problemu. Teraz widzę, że faktycznie przy wycinaniu białych znaków może być problem w zależności od wybranego kodowania i wiem, co naprawiać.

A problem z wyrażeniem (a właściwie lekcja) polega na tym, że predefiniowane klasy wyrażeń można rozbić o kant czterech liter, bo jak widzisz - jakiś ynteligent do grona białych znaków, do którego każdy normalny człowiek zaliczy spację, tabulator i znaki zejścia do nowej linii, wliczył jeszcze tzw. spację niełamalną reprezentowaną przez encję &nbsp; która ma zupełnie inny kod i zgadzam się jak najbardziej, że stripWhitespaces nie powinno jej kasować.

Poprawki znajdą się w repozytorium w ciągu najbliższych dni i będą uwzględnione w OPT 2.0.7 i OPT 2.1.0.
Logged

PozDrX, Zyx
---Invenzzia group---
Zyx
Your programmer
Administrator
User
*****
Offline Offline

Posts: 291



View Profile WWW
« Reply #12 on: November 19, 2010, 08:11:24 »

OK, poprawka jest już wgrana, ale w sumie za bardzo nie miałem tego jak poprawiać, ponieważ o dziwo u mnie wszystko działało dobrze nawet bez tej opcji. Widocznie jest to zależne od systemu, biblioteki PCRE i paru innych czynników. Na wszelki wypadek zatem dodałem generowanie modyfikatora "/u" przy włączonym Unikodzie. Mi to nie przeszkadza, a Tobie może pomoże.
Logged

PozDrX, Zyx
---Invenzzia group---
Pages: [1]   Go Up
  Print  
 
Jump to:  

Subject Started by Replies Views Last post
OPTv2: Walidacja szablonów Kozack 9 845 Last post November 24, 2010, 20:20:32
by Zyx
OPTv2: Opt sam zamyka znaczniki Agares 4 1341 Last post August 12, 2008, 20:59:33
by Zyx
OPTv2: Tworzenie bloków Wojnar 5 586 Last post December 19, 2010, 18:55:52
by Wojnar
OPTv2: SVN: Brak opt:tree. megaweb 4 1113 Last post October 20, 2008, 20:32:26
by megaweb
OPT: problem z parsowaniem (Warning : filemtime() [function.filemtime]: stat failed) Gaza 2 1339 Last post May 29, 2008, 08:29:26
by Gaza