URL이 차단되어 있더라도 해당 위치에 남겨 두시기 바랍니다. 포럼 사용 사례에 대해 그렇게 하는 것이 합리적인지 여부를 논의해 볼 수 있지만, 크롤링이 차단된 상태에서도 URL은 명료성 확보에 도움이 될 수 있습니다.
이것은 여전히 정중한 요청일 뿐이며, 구글조차도 항상 이를 존중하지는 않습니다. 예를 들어, Gmail 내 링크는 구글봇을 즉시 해당 URL로 보내며, 충분한 방문 횟수는 인덱싱과 검색 결과로 이어집니다.
게다가… 우리(또는 당신)는 미래에 상황이 어떻게 변할지 알 수 없습니다. 지금 해결해 두면 나중에 걱정할 필요가 없습니다. 물론 작업 시간이 필요하지만, 투자와 논의도 마찬가지입니다 ![]()
이제 first page의 DiscussionForumPosting에 대한 속성 datePublished가 page=2+의 datePublished와 다르게 나타납니다!
first page:
2015-07-05T22:02:58Zpage=2+:
2015-07-05T22:02:57Z
Google은 불일치하는 데이터를 신뢰하지 않을 것이며, 이로 인해 두 URL이 서로 다른 DiscussionForumPosting을 포함하고 있어 결합할 수 없다고 판단할 수 있습니다.
first page와 page=2+에서 동일한 데이터 소스를 사용하는 것이 좋습니다.
예를 들어, 항상 토픽의 datePublished를 사용하고 첫 번째 게시글의 것은 사용하지 않는 것 등입니다.
first page에 대한 search.google.com/test/rich-results
datePublished: 2015-07-05T22:02:58Z
page=2에 대한 search.google.com/test/rich-results
datePublished: 2015-07-05T22:02:57Z
PR:
항상
datePublished는 토픽에서 가져오고first_post에서는 가져오지 않습니다. 이를 통해first page와page=2+에서datePublished가 일관되게 유지됩니다.
page=2+에서text를 반복할 필요는 없습니다. 특히text가 요약일 뿐이며first page의text와 100% 일치하지 않는 경우page=2+에text를 설정하지 마십시오.
Google Search Console에서 의도치 않은 결과가 발생: 후속 페이지page=2+에서text속성을 유지하십시오.
크롤러 보기에서 “x일 전 닫힘” 게시글 숨기기
토픽이 닫히면 해당 토픽에 특수 게시글이 추가됩니다:
예를 들어 Google structured data for forums and profile pages - #14 by techAPJ 참조
물론 이 게시글은 없 text 속성이 비어 있습니다. validator.schema.org for …/t/-/286762 → 마지막 댓글 참조:
Google 검색 콘솔 보고서
결론
따라서 이러한 특수한 시스템/공지 게시글은 크롤러 보기에서 제외되어야 합니다.
PR
특수한 시스템/공지 게시글은 콘텐츠가 없으므로 크롤러 보기에서 제외됩니다.
빈 콘텐츠는 Google 검색 콘솔에서 비치명적 문제인 '필드 “text” 누락 (“comment” 내)'을 유발합니다.
가용한 경우, 저자 이름 메타데이터를 전체 이름 프로필 필드로 설정하는 것이 더 합리적일까요? 적어도 prioritize username in ux가 비활성화된 포럼에서는 그렇습니다(다만, URL 필드가 이미 구분을 해주므로 어느 쪽이든 괜찮다고 생각합니다).
이 문제를 해결할 수 있는 방법이 있나요, 아니면 discourse 팀이 코어를 업데이트해야 하나요?
@rrlevering 이 “후속 페이지에 text 속성이 필요 없음” / IsExternalContent() 검사에 대해:
실제 도메인에서 이 테스트 케이스를 가지고 있습니다:
Discourse는 다음에 DiscussionForumPosting을 구현합니다 …
첫 번째 페이지- 페이지 URL: https://example.org/t/-/12345- 속성
url:https://example.org/t/-/12345 - 속성
text: 설정됨 - 속성
author: – 설정됨 –
- 속성
page=2- 페이지 URL: https://example.org/t/-/12345?page=2- 속성
url:https://example.org/t/-/12345 - 속성
text: 전혀 설정되지 않음 - 속성
author: – 설정됨 –
- 속성
결과: Google Search Console (실시간 테스트)
첫 번째 페이지:
DiscussionForumPosting유효page=2:
DiscussionForumPosting유효하지 않음중요 문제 1건–"text", "image", 또는 "video" 중 하나가 지정되어야 함
따라서 여기에는 IsExternalContent()에 대한 검사가 없거나, 검사에서 다음에 대해 페이지 URL이 속성 url과 같다고 가정하고 있습니다:
- 페이지 URL:
https://example.org/t/-/12345?page=2 - 속성
url:
https://example.org/t/-/12345
따라서 현재로서는 Google Search Console에서 유효한 DiscussionForumPosting을 얻으려면 후속 페이지에 속성 text를 반복해야 합니다.
DiscussionForumPosting에 대한 잘못된 스키마 마크업 - 특정 토픽/게시물 URL에만 해당
영향받는 토픽: 총 게시물이 20개를 초과하는 토픽
영향받는 URL: …/t/-/NNN/7부터 …/t/-/NNN/20까지
‘Google Rich Result Test’ 보고서
URL …/t/-/NNN/11: 총 게시물 수가 다른 다양한 토픽 (클릭하여 열기)
- 총 18개 게시물이 있는 토픽: …/t/-/283678/11 결과 유효
- 총 19개 게시물이 있는 토픽: …/t/-/235984/11 결과 유효
- 총 20개 게시물이 있는 토픽: …/t/-/264899/11 결과 무효
- 총 21개 게시물이 있는 토픽: …/t/-/282382/11 결과 무효
– 모든 예시 토픽은 총 게시물 수가 변하지 않도록 ‘닫힘(closed)’ 상태로 설정되어 있습니다. 이 버그 자체도 ‘열림(open)’ 상태의 토픽에도 영향을 미칩니다! –
URLs …/t/-/16968/1부터 …/t/-/16968/38까지: 현재 38개 게시물이 있는 하나의 토픽 (클릭하여 열기)
유효한 스키마 마크업:
– DiscussionForumPosting 자체에는 여전히 불필요한 속성 position: 1이 있습니다. –
- …/t/-/16968 결과:
Comment위치 2~20 - …/t/-/16968/1 결과:
Comment위치 2~20 - …
- …/t/-/16968/6 결과
Comment위치 2~20.
무효한 스키마 마크업: author/datePublished 누락
- …/t/-/16968/7 결과
Comment위치 2~21. - …/t/-/16968/8 결과
Comment위치 3~22. - …
- …/t/-/16968/20 결과
Comment위치 15~34.
다시 유효한 스키마 마크업: (여기서: @page > 1은 true임):
-
…/t/-/16968/21 결과:
Comment위치 16~35 -
…/t/-/16968/22 결과:
Comment위치 17~36 -
…
-
…/t/-/16968/24 결과:
Comment위치 19~38 -
…/t/-/16968/25 결과: 현재 포함
Comment위치 19~38 -
…
-
…/t/-/16968/38 결과 – 현재 마지막 게시물: 현재 포함
Comment위치 19~38 -
…
-
…/t/-/16968/999 결과 – 존재하지 않는 높은 번호의 게시물: 현재 포함
Comment위치 19~38
기술적 고려 사항
1. `@topic_view.prev_page`는 `author`/`datePublished`를 표시할지 여부를 결정하는 데 최선의 해결책이 아닐 수 있습니다.
app/views/topics/show.html.erb#L53-L60
<% if @topic_view.prev_page %>
<meta itemprop='datePublished' content='<%= @topic_view.topic.created_at.to_formatted_s(:iso8601) %>'>
<span itemprop='author' itemscope itemtype="http://schema.org/Person">
<meta itemprop='name' content='<%= @topic_view.topic.user.username %>'>
<link itemprop='url' href='<%= Discourse.base_url %>/u/<%= @topic_view.topic.user.username %>'>
</span>
<meta itemprop='text' content='<%= @topic_view.topic.excerpt %>'>
<% end %>
2. `@topic_view.prev_page`의 구현 자체가 버그가 있을 수 있습니다.
lib/topic_view.rb#L113-L115
lib/topic_view.rb#L128-L130
lib/topic_view.rb#L193-L195
@post_number = [@post_number.to_i, 1].max
# ---
@page = @page.to_i > 1 ? @page.to_i : calculate_page
# ---
def prev_page
@page > 1 && posts.size > 0 ? @page - 1 : nil
end
여기에 버그가 있는가?
lib/topic_view.rb#L751-L755
def calculate_page
posts_count =
is_mega_topic? ? @post_number : unfiltered_posts.where("post_number <= ?", @post_number).count
((posts_count - 1) / @limit) + 1
end
calculate_page는 현재@post_number를 사용하며 7~20 값에서 실패할 수 있어 예상치 못한 결과를 줄 수 있습니다.((posts_count - 1) / @limit) + 1의 결과는 다음과 같습니다:
((7 - 1) / 20) + 1 = 1.3 = 1- 예상되는 페이지 번호는 얼마인가? 아마도 정수가 아닌 값으로 계산한 후
floor/ceil을 통해 의도대로 반올림하고 정수로 타입 캐스팅해야 할 것입니다:
(((posts_count - 1.0) / (@limit + 0.0)) + 1.0).floor.to_i - 의도대로 post_1부터 모든 게시물을 포함하지 않을 수 있으므로
unfiltered_posts.where("post_number <= ?", @post_number)를@topic.posts와 비교하여 확인해 보십시오.
lib/topic_view.rb#L53-L55
lib/topic_view.rb#L119-L127
lib/topic_view.rb#L835-L841
def self.chunk_size
20
end
# ---
@chunk_size =
case
when @print
TopicView.print_chunk_size
else
TopicView.chunk_size
end
@limit ||= @chunk_size
# ---
def unfiltered_posts
result = filter_post_types(@topic.posts)
result = result.with_deleted if @guardian.can_see_deleted_posts?(@topic.category)
result = result.where("user_id IS NOT NULL") if @exclude_deleted_users
result = result.where(hidden: false) if @exclude_hidden
result
end
결론
이 경계 케이스에서 …
- 총 게시물이 20개를 초과하는 토픽
…/t/-/NNN/7부터…/t/-/NNN/20까지
… 첫 번째 게시물이 현재 뷰의 일부가 아니었고, 뷰가 여전히 첫 페이지에 있었기 때문에 @topic_view.prev_page가 트리거되지 않았습니다.
따라서 첫 번째 게시물의 컨텍스트 또는 @topic_view.prev_page == true일 때만 렌더링되던 마이크로데이터 스키마 DiscussionForumPosting의 모든 속성이 누락되었습니다.
PR
마이크로데이터 스키마
DiscussionForumPosting의 일부 속성은 첫 번째 게시물의 컨텍스트에서 렌더링됩니다. 첫 번째 게시물이 현재 뷰의 일부가 아닌 경우에도 이러한 속성이 설정되도록 보장하십시오.
음… 예상치 못한 일이네요. 불편을 드려 죄송합니다. URL 비교 검사에서 쿼리 파라미터가 비교 과정에서 누락되는 것 같습니다. 수정을 바로 배포하겠습니다.
이 수정에 대해 최신 업데이트가 있나요?
이번 주 배포된 수정 사항으로 인해 “이것이 외부 URL인지” 확인 시 쿼리 파라미터를 고려하도록 변경되었습니다. 따라서 쿼리 파라미터를 통해 다른 URL에서 OP를 참조하는 포럼(foo와 foo?page=2)의 경우 GSC에서 오류가 보고되지 않을 것입니다.
이번 주 배포된 수정 사항을 통해, "외부 URL인지"를 확인하는 과정에서 쿼리 파라미터를 고려하도록 변경되었습니다.
@rrlevering 다른 포럼 플랫폼에서는 스레드의 각 게시글에 대해 comment - Schema.org Property 스키마를 중첩(nesting)하는 것을 권장했습니다. Discourse에서는 이렇게 하지 않는 것으로 보입니다. 여전히 이 방식을 권장하시나요?
Discourse는 스레드의 각 게시물에 대해 Comment 스키마를 중첩(nest)합니다. Schema Markup Validator 확인하고 DiscussionForumPosting 객체를 열어 중첩된 댓글을 살펴보세요.
감사합니다! DiscussionForumPosting 안에 중첩되어 있어서 놓쳤습니다.




