diff --git a/app/controllers/tag_controller.rb b/app/controllers/tag_controller.rb index 4855c384f7..d508d22faa 100644 --- a/app/controllers/tag_controller.rb +++ b/app/controllers/tag_controller.rb @@ -242,6 +242,35 @@ def related render partial: 'tag/related', layout: false, locals: { tags: @tags } end + def subtopics + @topic = (params[:subtopic] || params[:topic] || params[:id]).to_s.strip + if @topic.blank? + @subtopics = [] + else + parent_tag = Tag.find_by(name: "parent:#{@topic}") + node_subtopics = parent_tag ? parent_tag.nodes.where(status: 1) : [] + node_slugs = node_subtopics.collect(&:slug).compact.uniq + + if node_slugs.present? + @subtopics = Tag.where(name: node_slugs).or(Tag.where(parent: @topic)).order(:name) + else + @subtopics = Tag.where(parent: @topic).order(:name) + end + + existing_names = @subtopics.collect(&:name) + missing_slugs = node_slugs - existing_names + if missing_slugs.present? + missing_tags = missing_slugs.map { |slug| Tag.new(name: slug) } + @subtopics = @subtopics.to_a + missing_tags + @subtopics.sort_by!(&:name) + end + end + + render partial: 'tag/subtopics', layout: false, locals: { subtopics: @subtopics, topic: @topic } + end + + def topic_tree; end + def widget num = params[:n] || 4 nids = Tag.find_nodes_by_type(params[:id], 'note', num).collect(&:nid) @@ -566,6 +595,4 @@ def fetch_counts @nodes.size end end - - def topic_tree; end end diff --git a/app/views/tag/_subtopic.html.erb b/app/views/tag/_subtopic.html.erb new file mode 100644 index 0000000000..336b1b62ac --- /dev/null +++ b/app/views/tag/_subtopic.html.erb @@ -0,0 +1 @@ +<%= render partial: 'tag/subtopics', locals: { subtopics: local_assigns[:subtopics] || @subtopics, topic: local_assigns[:topic] || @topic } %> diff --git a/app/views/tag/_subtopics.html.erb b/app/views/tag/_subtopics.html.erb new file mode 100644 index 0000000000..09c5a09bed --- /dev/null +++ b/app/views/tag/_subtopics.html.erb @@ -0,0 +1,19 @@ +<% list = local_assigns[:subtopics] || @subtopics %> +<% if list.present? %> + <% list.each do |subtopic| %> + <% name = subtopic.respond_to?(:name) ? subtopic.name : (subtopic.respond_to?(:slug) ? subtopic.slug : subtopic.to_s) %> +
+
+ +   + +  <%= name %> +
+ +
+ <% end %> +<% else %> +
+  No subtopics found +
+<% end %> diff --git a/app/views/tag/topic_tree.html.erb b/app/views/tag/topic_tree.html.erb index c6adf8c814..14664a2cab 100644 --- a/app/views/tag/topic_tree.html.erb +++ b/app/views/tag/topic_tree.html.erb @@ -1,107 +1,553 @@ -

Topic Tree

-
- - -
-
-
-  Water - -
- - -
-  Soil - -
- - -
-  Air - -
- -
-  Industry - -
- -
-  Climate - -
- -
-  Organizing - -
- -
-  Monitoring - -
- -
-
- - \ No newline at end of file +

Topic Tree

+
+ +
+
+
+  Water +
+
+
+ +   + +  drinking-water +
+ +
+
+
+ +   + +  fracking +
+ +
+
+
+ +   + +  microplastics +
+ +
+
+
+ +   + +  lead +
+ +
+
+
+ +   + +  mining +
+ +
+
+
+ +   + +  agriculture +
+ +
+
+
+ +   + +  oil-and-gas +
+ +
+
+
+ +   + +  filters +
+ +
+
+
+ +   + +  wastewater +
+ +
+
+
+ +
+  Soil +
+
+
+ +   + +  lead +
+ +
+
+
+ +   + +  mining +
+ +
+
+
+ +   + +  agriculture +
+ +
+
+
+ +   + +  oil-and-gas +
+ +
+
+
+ +
+  Air +
+
+
+ +   + +  indoor-air +
+ +
+
+
+ +   + +  formaldehyde +
+ +
+
+
+ +   + +  dust +
+ +
+
+
+ +   + +  particulate-matter +
+ +
+
+
+ +   + +  oil-and-gas +
+ +
+
+
+ +   + +  transportation +
+ +
+
+
+ +   + +  filters +
+ +
+
+
+ +
+  Industry +
+
+
+ +   + +  land-use +
+ +
+
+
+ +   + +  land-change +
+ +
+
+
+ +   + +  particulate-matter +
+ +
+
+
+ +   + +  oil-and-gas +
+ +
+
+
+ +   + +  transportation +
+ +
+
+
+ +   + +  mining +
+ +
+
+
+ +   + +  agriculture +
+ +
+
+
+ +   + +  waste +
+ +
+
+
+ +   + +  noise +
+ +
+
+
+ +   + +  chemicals +
+ +
+
+
+ +   + +  pipeline-monitoring +
+ +
+
+
+ +   + +  cafo +
+ +
+
+
+ +
+  Climate +
+
+
+ +   + +  stormwater +
+ +
+
+
+ +   + +  land-change +
+ +
+
+
+ +   + +  particulate-matter +
+ +
+
+
+ +   + +  oil-and-gas +
+ +
+
+
+ +
+  Organizing +
+
+
+ +   + +  advocacy +
+ +
+
+
+ +   + +  community-organizing +
+ +
+
+
+ +   + +  legal +
+ +
+
+
+ +   + +  public-comment +
+ +
+
+
+ +   + +  host-an-event +
+ +
+
+
+ +
+  Monitoring +
+
+
+ +   + +  air-sensors +
+ +
+
+
+ +   + +  water-sensors +
+ +
+
+
+ +   + +  balloon-mapping +
+ +
+
+
+ +   + +  study-design +
+ +
+
+
+ +   + +  other methods +
+ +
+
+
+ +
+
+ + + + diff --git a/config/routes.rb b/config/routes.rb index b7aafe7315..0089f41acf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -208,6 +208,8 @@ get 'blog2/:id' => 'tag#blog2' get 'tags' => 'tag#index' get 'tags/related(/:id)' => 'tag#related' + get 'tags/subtopics(/:subtopic)' => 'tag#subtopics' + get 'tags/subtopic(/:subtopic)' => 'tag#subtopics' get 'tags/:id' => redirect('/tag/:id') post 'tag/suggested/:id' => 'tag#suggested' get 'tag/author/:id.json' => 'tag#author' diff --git a/test/fixtures/node_tags.yml b/test/fixtures/node_tags.yml index 4f2be77509..511f1811cc 100644 --- a/test/fixtures/node_tags.yml +++ b/test/fixtures/node_tags.yml @@ -284,3 +284,10 @@ sub_tag: tid: 37 nid: 1 uid: 2 + +subtopic_node_tag: + tid: 38 + uid: 1 + nid: 2 + date: <%= DateTime.now.to_i %> + diff --git a/test/fixtures/tags.yml b/test/fixtures/tags.yml index 0fc023fc87..d95aa6317f 100644 --- a/test/fixtures/tags.yml +++ b/test/fixtures/tags.yml @@ -150,3 +150,12 @@ hidden_response_tag: subscribed_tag: tid: 37 name: sub:tag + +subtopic_parent_tag: + tid: 38 + name: parent:water + +subtopic_child_tag: + tid: 39 + name: about + diff --git a/test/functional/tag_controller_test.rb b/test/functional/tag_controller_test.rb index 0c60755709..89489155fd 100644 --- a/test/functional/tag_controller_test.rb +++ b/test/functional/tag_controller_test.rb @@ -694,4 +694,52 @@ def setup assert_not_nil comments assert_template 'comments/_comments' end + + test 'subtopics partial with parent column tag' do + get :subtopics, params: { subtopic: 'spectrometry' } + assert_response :success + assert_not_nil assigns(:subtopics) + assert_includes assigns(:subtopics).map(&:name), 'spectrometer' + assert_template partial: 'tag/_subtopics' + assert_select '.topic-item[data-topic="spectrometer"]' + end + + test 'subtopics partial with parent:tagname on node' do + get :subtopics, params: { subtopic: 'water' } + assert_response :success + assert_not_nil assigns(:subtopics) + assert_includes assigns(:subtopics).map(&:name), 'about' + assert_template partial: 'tag/_subtopics' + assert_select '.topic-item[data-topic="about"]' + end + + test 'subtopics accepts topic parameter alias' do + get :subtopics, params: { topic: 'water' } + assert_response :success + assert_not_nil assigns(:subtopics) + assert_includes assigns(:subtopics).map(&:name), 'about' + end + + test 'subtopics with missing or empty parameter' do + get :subtopics, params: { subtopic: '' } + assert_response :success + assert_equal [], assigns(:subtopics) + assert_select '.text-muted' + end + + test 'subtopics with nonexistent topic returns empty list message' do + get :subtopics, params: { subtopic: 'nonexistent-topic-xyz' } + assert_response :success + assert_equal [], assigns(:subtopics) + assert_select '.text-muted' + end + + test 'topic_tree page renders correctly with expandable topics' do + get :topic_tree + assert_response :success + assert_select '#accordion' + assert_select '.topic-item' + assert_select '.expand-btn' + assert_select '.subtopics-container' + end end