Extra Form
PHP PHP 7.2
CMS Rhymix 2.x

Context::getBodyClass() 의 값이 

 

class="name"

 

의 name 만 값을 가질 것이라고 예상하고 코드를 짰었는데

오늘 우연히 다른 것을 하려고 위 값을 찍어보게 되었는데

class="name" 전체를 가지고 있네요.....

 

 

 

  • profile
    넵 그렇게 가져오는게 의도된 동작입니다.

    라이믹스 테스트 하는 곳에서 해당 함수를 테스트하는데 결과값을 출력하는것이 같은 양식입니다.

    $this->assertEquals(Context::getBodyClass(), ' class="red"');
  • ?
    `Context::getInstance()->body_class`로 배열로 받을 수 있어요.
  • ? profile

    class 내용만 배열로 따로 받을 수 있나보네요.

    일단 preg_match('/검출문자/', Context::getBodyClass()) 이렇게만 해도 배열로 가지고 오지 않아도 될 것 같아 이렇게 하려구요.


    그런데 전 한가지 의문점이

    Context::addBodyClass() 함수는 기존 클래스에 추가를 해주는게 아니고 class를 통째로 바꾸는 거 같더라구요.
    이건 특별한 사정이 있는건지...  전 오히려 추가가 안되고 통째로 바뀌어서 편하긴 합니다.

  • profile ?

    Context::getInstance()->body_class 배열에
    addBodyClass()로 추가하고 getBodyClass()로 배열에서 클래스 목록을 가져와서 'class="..."'을 반환하는 구조입니다.

     

    통째로(?) 바뀐다는 게 이해하기 어렵습니다만 getBodyClass는 위 배열에 있는 class 목록을 합쳐서 반환해주는 것이니 그렇게 보일 수도 있을 것 같기는 하네요. 

    removeBodyClass() 같은건 없기 때문에 배열에서 unset()하면 제거되고요.

    https://github.com/rx-public/rxp_flex/blob/f8c99395e2cc7b08e748a946397f7776faa15088/_config.php#L120
    여기에서 사용되었습니다.

  • ? profile

    Context::addBodyClass() 를 하면 기존 클래스는 지워지고 입력한 class만 남습니다. 관련 함수를 아까 봤는데 찾아볼게요.

     

    https://github.com/rhymix/rhymix/blob/master/classes/context/Context.class.php#L2406

     

    위 함수에서 통째로 교체되는 결과가 나오지 않나요?

    public static function addBodyClass($class_name)

    {

    self::$_instance->body_class[] = $class_name;

    }

     

    저는 기존 class  name은 지워지고 새로 요청한 name만 남더든요. 이게 원하는 결과라 원래 그런줄 알았습니다.

  • profile ?
    'body_class[]' 이렇게 대괄호가 붙은 건 대체되지 않고 배열에 추가됩니다.
  • ? profile
    어... 그럼 결과가 다른데요.. 제다 다크모드와 라이트모드 관련해서 단순히
    Context::addBodyClass('color_scheme_dark');
    이렇게만 해줘서 좋은 결과? 가 나와서 그냥 사용했습니다.

    기존 class인 color_scheme_light 는 남지 않거든요.
  • profile profile
    기존에 color_scheme_light 클래스가 없었을 겁니다. 다크모드 자동 감지 기능에 의해 추가되는 클래스는 페이지를 사용자에게 전송한 후 JS에서 추가하는 것이므로, 페이지 전송 전에 서버단에서 확인하면 안 나올 가능성이 높습니다.

    참고로 서버단에서 추가한 것인지 JS에서 추가한 것인지 쉽게 구분하는 방법은 개발자도구와 소스보기(Ctrl+U)를 비교하는 것입니다. 개발자도구는 현재 상태를 보여주고 소스보기는 서버에서 전송한 내용 그대로를 보여주기 때문에, JS에서 추가한 내용은 개발자도구에만 나오고 소스보기에는 나오지 않습니다.
  • profile ?
    rxp flex레이아웃의 영향일 수도 있을 것 같네요.
    light나 dark 하나만 남기게 해놨거든요.

    add 한 뒤에 바로 debugPrint(Context::getBodyClass()) 등으로 결과를 확인해 보세요.
  • ? profile
    네. 한번 확인해보겠습니다.
  • ? profile
    디버그 찍어봤는데 2개가 찍히는 경우는 없고 항상 1개만 남습니다.

    if($_COOKIE['color_scheme'] == 'dark' && \Rhymix\Framework\UA::getColorScheme() === 'auto' && !preg_match('/color_scheme_dark/', Context::getBodyClass())):
    Context::addBodyClass('color_scheme_dark');
    debugPrint(Context::getBodyClass());
    endif;


    저기에 디버그가 심어져 있구요.

    기본적으로 color_scheme_light 클래스를 가진 상태에서 기기의 다크모드를 설정하고 새로고침하면 저 코드에 의해서 Context::addBodyClass('color_scheme_dark'); 가 작동해서 class가 바뀝니다.

    디버그 결과는

    '\' class="color_scheme_dark"\''

    항상 이렇게 하나만 찍힙니다.
  • ? profile
    public static function colorScheme()
    {
    if (self::$colorScheme) {
    return self::$colorScheme;
    }

    $config = self::getConfig();

    $colorScheme = \Rhymix\Framework\UA::getColorScheme();
    if ($config['color_scheme'] !== 'auto') {
    $colorScheme = $config['color_scheme'];
    if ($config['color_scheme'] === 'light') {
    $key = array_search('color_scheme_dark', Context::getInstance()->body_class);
    unset(Context::getInstance()->body_class[$key]);
    } elseif ($config['color_scheme'] === 'dark') {
    $key = array_search('color_scheme_light', Context::getInstance()->body_class);
    unset(Context::getInstance()->body_class[$key]);
    }
    Context::addBodyClass('color_scheme_' . $config['color_scheme']);
    }

    self::$colorScheme = $colorScheme;
    return self::$colorScheme;
    }


    레이아웃 자체기능에서 이 함수가 먼저 작동하는데 여기서 영향을 준다는 거죠???
    그럼 저 함수가 제거되었을 경우를 생각한다면 정석적인 방법으로 다시 코드를 정비해야겠네요??
  • profile
    결과값은 class=를 포함하여 나오는 것이 정상입니다. common/tpl/common_layout.html을 보시면 그 결과가 어디에 어떻게 들어가는지 짐작하실 수 있을 거예요. 아마 클래스가 하나도 없는 경우 class= 속성 자체를 출력하지 않도록 하려고 이렇게 구현한 것 같은데, 지저분하죠. ㅎㅎ

    다른 곳에서 추가한 클래스명을 삭제하고 통째로 바꾸지는 않습니다.

    @비엔유 Context::getInstance()->body_class와 같은 내부 자료구조에 직접 접근하여 조작하는 서드파티 자료는 예고 없이 지원이 중단될 수 있으니 주의하시기 바랍니다. 현재 지정된 클래스 목록을 배열로 받아오거나, 특정 클래스를 제거하는 기능이 필요하다면 해당 기능 추가를 정식으로 요청해 주세요.^^
  • profile profile
    그럼 저의 경우

    Context::addBodyClass('color_scheme_dark');
    만 해줬을때

    color_scheme_light 는 사라지고

    color_scheme_dark 만 남는건 어디서 이런 결과가 나오는 걸까요???
  • profile profile
    기존에 color_scheme_light 클래스가 없었을 겁니다. 다크모드 자동 감지 기능에 의해 추가되는 클래스는 페이지를 사용자에게 전송한 후 JS에서 추가하는 것이므로, 페이지 전송 전에 서버단에서 확인하면 안 나올 가능성이 높습니다.

    참고로 서버단에서 추가한 것인지 JS에서 추가한 것인지 쉽게 구분하는 방법은 개발자도구와 소스보기(Ctrl+U)를 비교하는 것입니다. 개발자도구는 현재 상태를 보여주고 소스보기는 서버에서 전송한 내용 그대로를 보여주기 때문에, JS에서 추가한 내용은 개발자도구에만 나오고 소스보기에는 나오지 않습니다.
  • profile profile

    이게 토글 형식으로 바꾸는 코드가 php로 작동하는거라 없을 수가 없는데요...
    일단 말씀하신 대로 확인은 해보겠습니다.

     

    개발자도구,소스보기 두곳 결과는 같습니다. 1개만 남아있어요.

  • profile ?
    코어 버그 때문에 임시로 조치한거고 라이믹스 다음 버전 배포되면 제거될 코드라서 상관없습니다.
  • ? profile
    아, 그렇군요. 다만 body class를 좀더 쉽게 다룰 수 있도록 메소드는 추가하는 것이 좋겠지요? ㅎㅎ
  • profile profile

    그럼 현재 Context::getInstance()->body_class 와 같은 내부 자료를 건드리지 않고 body class 클래스명을 토글하는 방법을 알 수 있을까요???

     

    color_scheme_light -> color_scheme_dark

  • profile profile
    현재로서는 없습니다. 그런데 이미 어떤 이유에선가 color_scheme_light는 사라지고 없다고 하셨으니 특별히 필요하지 않을 수도 있겠네요.
  • profile profile
    언급하신 Context::getInstance()->body_class 를 이용하는 임시로 들어간 함수의 영향으로 특별히 필요없는 상황인데 조만간 제거해야 하니 다른 방법으로 구현이 필요해 보여서요.
  • profile
    develop 브랜치에서 두 개의 함수가 추가되었습니다.

    Context::removeBodyClass($class_name) 특정한 이름의 클래스를 제거합니다.
    Context::getBodyClassList() 현재 추가된 클래스 목록을 배열로 반환합니다.
  • profile profile
    확인해보겠습니다. 감사합니다.
  • profile profile
    Context::removeBodyClass('color_scheme_light')
    Context::addBodyClass('color_scheme_dark');

    이렇게 순서대로 실행하면
    원하는 전환이 되는거네요?
  • profile profile
    네.